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 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1264 /* LLVM models this by returning an int */
1265 if (size < SIZEOF_VOID_P) {
1266 g_assert (cinfo->ret.nslots == 1);
1267 ret_type = LLVMIntType (size * 8);
1269 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1270 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1274 case LLVMArgFpStruct: {
1275 /* Vtype returned as a fp struct */
1276 LLVMTypeRef members [16];
1278 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1279 for (i = 0; i < cinfo->ret.nslots; ++i)
1280 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1281 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1284 case LLVMArgVtypeByRef:
1285 /* Vtype returned using a hidden argument */
1286 ret_type = LLVMVoidType ();
1288 case LLVMArgVtypeRetAddr:
1289 case LLVMArgScalarRetAddr:
1290 case LLVMArgGsharedvtFixed:
1291 case LLVMArgGsharedvtFixedVtype:
1292 case LLVMArgGsharedvtVariable:
1294 ret_type = LLVMVoidType ();
1300 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1302 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1304 * Has to be the first argument because of the sret argument attribute
1305 * FIXME: This might conflict with passing 'this' as the first argument, but
1306 * this is only used on arm64 which has a dedicated struct return register.
1308 cinfo->vret_arg_pindex = pindex;
1309 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1310 if (!ctx_ok (ctx)) {
1311 g_free (param_types);
1314 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1317 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1318 cinfo->rgctx_arg_pindex = pindex;
1319 param_types [pindex] = ctx->module->ptr_type;
1322 if (cinfo->imt_arg) {
1323 cinfo->imt_arg_pindex = pindex;
1324 param_types [pindex] = ctx->module->ptr_type;
1328 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1329 vret_arg_pindex = pindex;
1330 if (cinfo->vret_arg_index == 1) {
1331 /* Add the slots consumed by the first argument */
1332 LLVMArgInfo *ainfo = &cinfo->args [0];
1333 switch (ainfo->storage) {
1334 case LLVMArgVtypeInReg:
1335 for (j = 0; j < 2; ++j) {
1336 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1345 cinfo->vret_arg_pindex = vret_arg_pindex;
1348 if (vretaddr && vret_arg_pindex == pindex)
1349 param_types [pindex ++] = IntPtrType ();
1351 cinfo->this_arg_pindex = pindex;
1352 param_types [pindex ++] = ThisType ();
1353 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1355 if (vretaddr && vret_arg_pindex == pindex)
1356 param_types [pindex ++] = IntPtrType ();
1357 for (i = 0; i < sig->param_count; ++i) {
1358 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1360 if (vretaddr && vret_arg_pindex == pindex)
1361 param_types [pindex ++] = IntPtrType ();
1362 ainfo->pindex = pindex;
1364 switch (ainfo->storage) {
1365 case LLVMArgVtypeInReg:
1366 for (j = 0; j < 2; ++j) {
1367 switch (ainfo->pair_storage [j]) {
1369 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1374 g_assert_not_reached ();
1378 case LLVMArgVtypeByVal:
1379 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1382 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1385 case LLVMArgAsIArgs:
1386 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1389 case LLVMArgVtypeByRef:
1390 case LLVMArgScalarByRef:
1391 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1394 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1397 case LLVMArgAsFpArgs: {
1400 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1401 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1402 param_types [pindex ++] = LLVMDoubleType ();
1403 for (j = 0; j < ainfo->nslots; ++j)
1404 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1407 case LLVMArgVtypeAsScalar:
1408 g_assert_not_reached ();
1410 case LLVMArgGsharedvtFixed:
1411 case LLVMArgGsharedvtFixedVtype:
1412 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1414 case LLVMArgGsharedvtVariable:
1415 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1418 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1422 if (!ctx_ok (ctx)) {
1423 g_free (param_types);
1426 if (vretaddr && vret_arg_pindex == pindex)
1427 param_types [pindex ++] = IntPtrType ();
1428 if (ctx->llvm_only && cinfo->rgctx_arg) {
1429 /* Pass the rgctx as the last argument */
1430 cinfo->rgctx_arg_pindex = pindex;
1431 param_types [pindex] = ctx->module->ptr_type;
1435 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1436 g_free (param_types);
1442 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1444 return sig_to_llvm_sig_full (ctx, sig, NULL);
1448 * LLVMFunctionType1:
1450 * Create an LLVM function type from the arguments.
1452 static G_GNUC_UNUSED LLVMTypeRef
1453 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1456 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1460 * LLVMFunctionType1:
1462 * Create an LLVM function type from the arguments.
1464 static G_GNUC_UNUSED LLVMTypeRef
1465 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1466 LLVMTypeRef ParamType1,
1469 LLVMTypeRef param_types [1];
1471 param_types [0] = ParamType1;
1473 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1477 * LLVMFunctionType2:
1479 * Create an LLVM function type from the arguments.
1481 static G_GNUC_UNUSED LLVMTypeRef
1482 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1483 LLVMTypeRef ParamType1,
1484 LLVMTypeRef ParamType2,
1487 LLVMTypeRef param_types [2];
1489 param_types [0] = ParamType1;
1490 param_types [1] = ParamType2;
1492 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1496 * LLVMFunctionType3:
1498 * Create an LLVM function type from the arguments.
1500 static G_GNUC_UNUSED LLVMTypeRef
1501 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1502 LLVMTypeRef ParamType1,
1503 LLVMTypeRef ParamType2,
1504 LLVMTypeRef ParamType3,
1507 LLVMTypeRef param_types [3];
1509 param_types [0] = ParamType1;
1510 param_types [1] = ParamType2;
1511 param_types [2] = ParamType3;
1513 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1516 static G_GNUC_UNUSED LLVMTypeRef
1517 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1518 LLVMTypeRef ParamType1,
1519 LLVMTypeRef ParamType2,
1520 LLVMTypeRef ParamType3,
1521 LLVMTypeRef ParamType4,
1522 LLVMTypeRef ParamType5,
1525 LLVMTypeRef param_types [5];
1527 param_types [0] = ParamType1;
1528 param_types [1] = ParamType2;
1529 param_types [2] = ParamType3;
1530 param_types [3] = ParamType4;
1531 param_types [4] = ParamType5;
1533 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1539 * Create an LLVM builder and remember it so it can be freed later.
1541 static LLVMBuilderRef
1542 create_builder (EmitContext *ctx)
1544 LLVMBuilderRef builder = LLVMCreateBuilder ();
1546 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1552 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1557 case MONO_PATCH_INFO_INTERNAL_METHOD:
1558 name = g_strdup_printf ("jit_icall_%s", data);
1560 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1561 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1562 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1566 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1574 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1578 LLVMValueRef indexes [2];
1580 LLVMValueRef got_entry_addr, load;
1581 LLVMBuilderRef builder = ctx->builder;
1586 ji = g_new0 (MonoJumpInfo, 1);
1588 ji->data.target = data;
1590 ji = mono_aot_patch_info_dup (ji);
1592 ji->next = cfg->patch_info;
1593 cfg->patch_info = ji;
1595 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1596 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1598 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1599 * explicitly initialize it.
1601 if (!mono_aot_is_shared_got_offset (got_offset)) {
1602 //mono_print_ji (ji);
1604 ctx->has_got_access = TRUE;
1607 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1608 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1609 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1611 name = get_aotconst_name (type, data, got_offset);
1613 load = LLVMBuildLoad (builder, got_entry_addr, "");
1614 load = convert (ctx, load, llvm_type);
1615 LLVMSetValueName (load, name ? name : "");
1617 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1620 //set_invariant_load_flag (load);
1626 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1628 return get_aotconst_typed (ctx, type, data, NULL);
1632 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1634 LLVMValueRef callee;
1636 if (ctx->llvm_only) {
1637 callee_name = mono_aot_get_direct_call_symbol (type, data);
1639 /* Directly callable */
1641 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1643 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1645 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1647 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1649 /* LLVMTypeRef's are uniqued */
1650 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1651 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1653 g_free (callee_name);
1659 * Calls are made through the GOT.
1661 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1663 MonoJumpInfo *ji = NULL;
1665 callee_name = mono_aot_get_plt_symbol (type, data);
1669 if (ctx->cfg->compile_aot)
1670 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1671 mono_add_patch_info (ctx->cfg, 0, type, data);
1674 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1676 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1678 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1680 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1683 if (ctx->cfg->compile_aot) {
1684 ji = g_new0 (MonoJumpInfo, 1);
1686 ji->data.target = data;
1688 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1696 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1698 MonoMethodHeader *header = cfg->header;
1699 MonoExceptionClause *clause;
1703 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1704 return (bb->region >> 8) - 1;
1707 for (i = 0; i < header->num_clauses; ++i) {
1708 clause = &header->clauses [i];
1710 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1717 static MonoExceptionClause *
1718 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1720 // Since they're sorted by nesting we just need
1721 // the first one that the bb is a member of
1722 MonoExceptionClause *last = NULL;
1724 for (int i = 0; i < cfg->header->num_clauses; i++) {
1725 MonoExceptionClause *curr = &cfg->header->clauses [i];
1727 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1730 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1731 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1745 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1747 LLVMValueRef md_arg;
1750 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1751 md_arg = LLVMMDString ("mono", 4);
1752 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1756 set_invariant_load_flag (LLVMValueRef v)
1758 LLVMValueRef md_arg;
1760 const char *flag_name;
1762 // FIXME: Cache this
1763 flag_name = "invariant.load";
1764 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1765 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1766 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1772 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1776 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1778 MonoCompile *cfg = ctx->cfg;
1779 LLVMValueRef lcall = NULL;
1780 LLVMBuilderRef builder = *builder_ref;
1781 MonoExceptionClause *clause;
1783 if (ctx->llvm_only) {
1784 clause = get_most_deep_clause (cfg, ctx, bb);
1787 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1790 * Have to use an invoke instead of a call, branching to the
1791 * handler bblock of the clause containing this bblock.
1793 intptr_t key = CLAUSE_END(clause);
1795 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1797 // FIXME: Find the one that has the lowest end bound for the right start address
1798 // FIXME: Finally + nesting
1801 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1804 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1806 builder = ctx->builder = create_builder (ctx);
1807 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1809 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1813 int clause_index = get_handler_clause (cfg, bb);
1815 if (clause_index != -1) {
1816 MonoMethodHeader *header = cfg->header;
1817 MonoExceptionClause *ec = &header->clauses [clause_index];
1818 MonoBasicBlock *tblock;
1819 LLVMBasicBlockRef ex_bb, noex_bb;
1822 * Have to use an invoke instead of a call, branching to the
1823 * handler bblock of the clause containing this bblock.
1826 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1828 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1831 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1833 ex_bb = get_bb (ctx, tblock);
1835 noex_bb = gen_bb (ctx, "NOEX_BB");
1838 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1840 builder = ctx->builder = create_builder (ctx);
1841 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1843 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1848 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1849 ctx->builder = builder;
1853 *builder_ref = ctx->builder;
1859 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1861 const char *intrins_name;
1862 LLVMValueRef args [16], res;
1863 LLVMTypeRef addr_type;
1865 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1866 LLVMAtomicOrdering ordering;
1869 case LLVM_BARRIER_NONE:
1870 ordering = LLVMAtomicOrderingNotAtomic;
1872 case LLVM_BARRIER_ACQ:
1873 ordering = LLVMAtomicOrderingAcquire;
1875 case LLVM_BARRIER_SEQ:
1876 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1879 g_assert_not_reached ();
1884 * We handle loads which can fault by calling a mono specific intrinsic
1885 * using an invoke, so they are handled properly inside try blocks.
1886 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1887 * are marked with IntrReadArgMem.
1891 intrins_name = "llvm.mono.load.i8.p0i8";
1894 intrins_name = "llvm.mono.load.i16.p0i16";
1897 intrins_name = "llvm.mono.load.i32.p0i32";
1900 intrins_name = "llvm.mono.load.i64.p0i64";
1903 g_assert_not_reached ();
1906 addr_type = LLVMTypeOf (addr);
1907 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1908 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1911 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1912 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1913 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1914 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1916 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1917 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1918 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1919 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1926 * We emit volatile loads for loads which can fault, because otherwise
1927 * LLVM will generate invalid code when encountering a load from a
1930 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1932 /* Mark it with a custom metadata */
1935 set_metadata_flag (res, "mono.faulting.load");
1943 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1945 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1949 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1951 const char *intrins_name;
1952 LLVMValueRef args [16];
1954 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1955 LLVMAtomicOrdering ordering;
1958 case LLVM_BARRIER_NONE:
1959 ordering = LLVMAtomicOrderingNotAtomic;
1961 case LLVM_BARRIER_REL:
1962 ordering = LLVMAtomicOrderingRelease;
1964 case LLVM_BARRIER_SEQ:
1965 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1968 g_assert_not_reached ();
1974 intrins_name = "llvm.mono.store.i8.p0i8";
1977 intrins_name = "llvm.mono.store.i16.p0i16";
1980 intrins_name = "llvm.mono.store.i32.p0i32";
1983 intrins_name = "llvm.mono.store.i64.p0i64";
1986 g_assert_not_reached ();
1989 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1990 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1991 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1996 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1997 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1998 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1999 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2001 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2006 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2008 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2012 * emit_cond_system_exception:
2014 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2015 * Might set the ctx exception.
2018 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2020 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2021 LLVMBuilderRef builder;
2022 MonoClass *exc_class;
2023 LLVMValueRef args [2];
2024 LLVMValueRef callee;
2026 ex_bb = gen_bb (ctx, "EX_BB");
2028 ex2_bb = gen_bb (ctx, "EX2_BB");
2029 noex_bb = gen_bb (ctx, "NOEX_BB");
2031 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2033 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2034 g_assert (exc_class);
2036 /* Emit exception throwing code */
2037 ctx->builder = builder = create_builder (ctx);
2038 LLVMPositionBuilderAtEnd (builder, ex_bb);
2040 if (ctx->cfg->llvm_only) {
2041 static LLVMTypeRef sig;
2044 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2045 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2047 LLVMBuildBr (builder, ex2_bb);
2049 ctx->builder = builder = create_builder (ctx);
2050 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2052 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2053 emit_call (ctx, bb, &builder, callee, args, 1);
2054 LLVMBuildUnreachable (builder);
2056 ctx->builder = builder = create_builder (ctx);
2057 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2059 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2065 callee = ctx->module->throw_corlib_exception;
2068 const char *icall_name;
2070 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2071 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2073 if (ctx->cfg->compile_aot) {
2074 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2076 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2079 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2080 * - On x86, LLVM generated code doesn't push the arguments
2081 * - The trampoline takes the throw address as an arguments, not a pc offset.
2083 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2085 mono_memory_barrier ();
2086 ctx->module->throw_corlib_exception = callee;
2090 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2091 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2093 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2096 * The LLVM mono branch contains changes so a block address can be passed as an
2097 * argument to a call.
2099 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2100 emit_call (ctx, bb, &builder, callee, args, 2);
2102 LLVMBuildUnreachable (builder);
2104 ctx->builder = builder = create_builder (ctx);
2105 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2107 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2114 * emit_args_to_vtype:
2116 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2119 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2121 int j, size, nslots;
2123 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2125 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2126 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2129 if (ainfo->storage == LLVMArgAsFpArgs)
2130 nslots = ainfo->nslots;
2134 for (j = 0; j < nslots; ++j) {
2135 LLVMValueRef index [2], addr, daddr;
2136 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2137 LLVMTypeRef part_type;
2139 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2142 if (ainfo->pair_storage [j] == LLVMArgNone)
2145 switch (ainfo->pair_storage [j]) {
2146 case LLVMArgInIReg: {
2147 part_type = LLVMIntType (part_size * 8);
2148 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2149 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2150 addr = LLVMBuildGEP (builder, address, index, 1, "");
2152 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2153 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2154 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2156 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2159 case LLVMArgInFPReg: {
2160 LLVMTypeRef arg_type;
2162 if (ainfo->esize == 8)
2163 arg_type = LLVMDoubleType ();
2165 arg_type = LLVMFloatType ();
2167 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2168 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2169 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2170 LLVMBuildStore (builder, args [j], addr);
2176 g_assert_not_reached ();
2179 size -= sizeof (gpointer);
2184 * emit_vtype_to_args:
2186 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2187 * into ARGS, and the number of arguments into NARGS.
2190 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2193 int j, size, nslots;
2194 LLVMTypeRef arg_type;
2196 size = get_vtype_size (t);
2198 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2199 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2201 if (ainfo->storage == LLVMArgAsFpArgs)
2202 nslots = ainfo->nslots;
2205 for (j = 0; j < nslots; ++j) {
2206 LLVMValueRef index [2], addr, daddr;
2207 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2209 if (ainfo->pair_storage [j] == LLVMArgNone)
2212 switch (ainfo->pair_storage [j]) {
2214 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2215 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2216 addr = LLVMBuildGEP (builder, address, index, 1, "");
2218 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2219 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2220 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2222 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2224 case LLVMArgInFPReg:
2225 if (ainfo->esize == 8)
2226 arg_type = LLVMDoubleType ();
2228 arg_type = LLVMFloatType ();
2229 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2230 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2231 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2232 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2237 g_assert_not_reached ();
2239 size -= sizeof (gpointer);
2246 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2249 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2250 * get executed every time control reaches them.
2252 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2254 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2255 return ctx->last_alloca;
2259 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2261 return build_alloca_llvm_type_name (ctx, t, align, "");
2265 build_alloca (EmitContext *ctx, MonoType *t)
2267 MonoClass *k = mono_class_from_mono_type (t);
2270 g_assert (!mini_is_gsharedvt_variable_type (t));
2272 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2275 align = mono_class_min_align (k);
2277 /* Sometimes align is not a power of 2 */
2278 while (mono_is_power_of_two (align) == -1)
2281 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2285 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2289 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2291 MonoCompile *cfg = ctx->cfg;
2292 LLVMBuilderRef builder = ctx->builder;
2293 LLVMValueRef offset, offset_var;
2294 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2295 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2299 g_assert (info_var);
2300 g_assert (locals_var);
2302 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2304 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2305 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2307 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2308 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2310 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2314 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2317 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2320 module->used = g_ptr_array_sized_new (16);
2321 g_ptr_array_add (module->used, global);
2325 emit_llvm_used (MonoLLVMModule *module)
2327 LLVMModuleRef lmodule = module->lmodule;
2328 LLVMTypeRef used_type;
2329 LLVMValueRef used, *used_elem;
2335 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2336 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2337 used_elem = g_new0 (LLVMValueRef, module->used->len);
2338 for (i = 0; i < module->used->len; ++i)
2339 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2340 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2341 LLVMSetLinkage (used, LLVMAppendingLinkage);
2342 LLVMSetSection (used, "llvm.metadata");
2348 * Emit a function mapping method indexes to their code
2351 emit_get_method (MonoLLVMModule *module)
2353 LLVMModuleRef lmodule = module->lmodule;
2354 LLVMValueRef func, switch_ins, m;
2355 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2356 LLVMBasicBlockRef *bbs;
2358 LLVMBuilderRef builder;
2363 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2364 * but generating code seems safer.
2366 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2367 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2368 LLVMSetLinkage (func, LLVMExternalLinkage);
2369 LLVMSetVisibility (func, LLVMHiddenVisibility);
2370 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2371 module->get_method = func;
2373 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2376 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2377 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2378 * then we will have to find another solution.
2381 name = g_strdup_printf ("BB_CODE_START");
2382 code_start_bb = LLVMAppendBasicBlock (func, name);
2384 builder = LLVMCreateBuilder ();
2385 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2386 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2388 name = g_strdup_printf ("BB_CODE_END");
2389 code_end_bb = LLVMAppendBasicBlock (func, name);
2391 builder = LLVMCreateBuilder ();
2392 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2393 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2395 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2396 for (i = 0; i < module->max_method_idx + 1; ++i) {
2397 name = g_strdup_printf ("BB_%d", i);
2398 bb = LLVMAppendBasicBlock (func, name);
2402 builder = LLVMCreateBuilder ();
2403 LLVMPositionBuilderAtEnd (builder, bb);
2405 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2407 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2409 LLVMBuildRet (builder, LLVMConstNull (rtype));
2412 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2413 builder = LLVMCreateBuilder ();
2414 LLVMPositionBuilderAtEnd (builder, fail_bb);
2415 LLVMBuildRet (builder, LLVMConstNull (rtype));
2417 builder = LLVMCreateBuilder ();
2418 LLVMPositionBuilderAtEnd (builder, entry_bb);
2420 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2421 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2422 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2423 for (i = 0; i < module->max_method_idx + 1; ++i) {
2424 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2427 mark_as_used (module, func);
2431 * emit_get_unbox_tramp:
2433 * Emit a function mapping method indexes to their unbox trampoline
2436 emit_get_unbox_tramp (MonoLLVMModule *module)
2438 LLVMModuleRef lmodule = module->lmodule;
2439 LLVMValueRef func, switch_ins, m;
2440 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2441 LLVMBasicBlockRef *bbs;
2443 LLVMBuilderRef builder;
2447 /* Similar to emit_get_method () */
2449 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2450 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2451 LLVMSetLinkage (func, LLVMExternalLinkage);
2452 LLVMSetVisibility (func, LLVMHiddenVisibility);
2453 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2454 module->get_unbox_tramp = func;
2456 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2458 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2459 for (i = 0; i < module->max_method_idx + 1; ++i) {
2460 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2464 name = g_strdup_printf ("BB_%d", i);
2465 bb = LLVMAppendBasicBlock (func, name);
2469 builder = LLVMCreateBuilder ();
2470 LLVMPositionBuilderAtEnd (builder, bb);
2472 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2475 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2476 builder = LLVMCreateBuilder ();
2477 LLVMPositionBuilderAtEnd (builder, fail_bb);
2478 LLVMBuildRet (builder, LLVMConstNull (rtype));
2480 builder = LLVMCreateBuilder ();
2481 LLVMPositionBuilderAtEnd (builder, entry_bb);
2483 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2484 for (i = 0; i < module->max_method_idx + 1; ++i) {
2485 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2489 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2492 mark_as_used (module, func);
2495 /* Add a function to mark the beginning of LLVM code */
2497 emit_llvm_code_start (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2501 LLVMBasicBlockRef entry_bb;
2502 LLVMBuilderRef builder;
2504 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2505 LLVMSetLinkage (func, LLVMInternalLinkage);
2506 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2507 module->code_start = func;
2508 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2509 builder = LLVMCreateBuilder ();
2510 LLVMPositionBuilderAtEnd (builder, entry_bb);
2511 LLVMBuildRetVoid (builder);
2515 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2517 LLVMModuleRef lmodule = module->lmodule;
2518 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2519 LLVMBasicBlockRef entry_bb;
2520 LLVMBuilderRef builder;
2527 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2528 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2533 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2534 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2537 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2538 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2541 g_assert_not_reached ();
2543 LLVMSetLinkage (func, LLVMInternalLinkage);
2544 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2545 mono_llvm_set_preserveall_cc (func);
2546 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2547 builder = LLVMCreateBuilder ();
2548 LLVMPositionBuilderAtEnd (builder, entry_bb);
2551 ji = g_new0 (MonoJumpInfo, 1);
2552 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2553 ji = mono_aot_patch_info_dup (ji);
2554 got_offset = mono_aot_get_got_offset (ji);
2555 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2556 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2557 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2558 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2559 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2560 args [1] = LLVMGetParam (func, 0);
2562 args [2] = LLVMGetParam (func, 1);
2564 ji = g_new0 (MonoJumpInfo, 1);
2565 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2566 ji->data.name = icall_name;
2567 ji = mono_aot_patch_info_dup (ji);
2568 got_offset = mono_aot_get_got_offset (ji);
2569 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2570 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2571 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2572 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2573 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2574 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2575 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2577 // Set the inited flag
2578 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2579 indexes [1] = LLVMGetParam (func, 0);
2580 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2582 LLVMBuildRetVoid (builder);
2584 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2589 * Emit wrappers around the C icalls used to initialize llvm methods, to
2590 * make the calling code smaller and to enable usage of the llvm
2591 * PreserveAll calling convention.
2594 emit_init_icall_wrappers (MonoLLVMModule *module)
2596 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2597 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2598 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2599 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2603 emit_llvm_code_end (MonoLLVMModule *module)
2605 LLVMModuleRef lmodule = module->lmodule;
2607 LLVMBasicBlockRef entry_bb;
2608 LLVMBuilderRef builder;
2610 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2611 LLVMSetLinkage (func, LLVMInternalLinkage);
2612 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2613 module->code_end = func;
2614 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2615 builder = LLVMCreateBuilder ();
2616 LLVMPositionBuilderAtEnd (builder, entry_bb);
2617 LLVMBuildRetVoid (builder);
2621 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2623 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2626 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2627 need_div_check = TRUE;
2629 if (!need_div_check)
2632 switch (ins->opcode) {
2645 case OP_IDIV_UN_IMM:
2646 case OP_LDIV_UN_IMM:
2647 case OP_IREM_UN_IMM:
2648 case OP_LREM_UN_IMM: {
2650 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2651 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2653 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2654 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2657 builder = ctx->builder;
2659 /* b == -1 && a == 0x80000000 */
2661 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2662 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2663 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2665 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2666 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2669 builder = ctx->builder;
2681 * Emit code to initialize the GOT slots used by the method.
2684 emit_init_method (EmitContext *ctx)
2686 LLVMValueRef indexes [16], args [16], callee;
2687 LLVMValueRef inited_var, cmp, call;
2688 LLVMBasicBlockRef inited_bb, notinited_bb;
2689 LLVMBuilderRef builder = ctx->builder;
2690 MonoCompile *cfg = ctx->cfg;
2692 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2694 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2695 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2696 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2698 args [0] = inited_var;
2699 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2700 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2702 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2704 inited_bb = ctx->inited_bb;
2705 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2707 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2709 builder = ctx->builder = create_builder (ctx);
2710 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2713 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2714 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2715 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2716 callee = ctx->module->init_method_gshared_mrgctx;
2717 call = LLVMBuildCall (builder, callee, args, 2, "");
2718 } else if (ctx->rgctx_arg) {
2719 /* A vtable is passed as the rgctx argument */
2720 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2721 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2722 callee = ctx->module->init_method_gshared_vtable;
2723 call = LLVMBuildCall (builder, callee, args, 2, "");
2724 } else if (cfg->gshared) {
2725 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2726 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2727 callee = ctx->module->init_method_gshared_this;
2728 call = LLVMBuildCall (builder, callee, args, 2, "");
2730 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2731 callee = ctx->module->init_method;
2732 call = LLVMBuildCall (builder, callee, args, 1, "");
2736 * This enables llvm to keep arguments in their original registers/
2737 * scratch registers, since the call will not clobber them.
2739 mono_llvm_set_call_preserveall_cc (call);
2741 LLVMBuildBr (builder, inited_bb);
2742 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2744 builder = ctx->builder = create_builder (ctx);
2745 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2749 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2752 * Emit unbox trampoline using a tail call
2754 LLVMValueRef tramp, call, *args;
2755 LLVMBuilderRef builder;
2756 LLVMBasicBlockRef lbb;
2757 LLVMCallInfo *linfo;
2761 tramp_name = g_strdup_printf ("ut_%s", method_name);
2762 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2763 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2764 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2765 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2767 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2768 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2769 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2770 if (ctx->cfg->vret_addr) {
2771 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2772 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2773 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2774 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2778 lbb = LLVMAppendBasicBlock (tramp, "");
2779 builder = LLVMCreateBuilder ();
2780 LLVMPositionBuilderAtEnd (builder, lbb);
2782 nargs = LLVMCountParamTypes (method_type);
2783 args = g_new0 (LLVMValueRef, nargs);
2784 for (i = 0; i < nargs; ++i) {
2785 args [i] = LLVMGetParam (tramp, i);
2786 if (i == ctx->this_arg_pindex) {
2787 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2789 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2790 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2791 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2794 call = LLVMBuildCall (builder, method, args, nargs, "");
2795 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2796 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2797 if (linfo->ret.storage == LLVMArgVtypeByRef)
2798 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2800 // FIXME: This causes assertions in clang
2801 //mono_llvm_set_must_tail (call);
2802 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2803 LLVMBuildRetVoid (builder);
2805 LLVMBuildRet (builder, call);
2807 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2813 * Emit code to load/convert arguments.
2816 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2819 MonoCompile *cfg = ctx->cfg;
2820 MonoMethodSignature *sig = ctx->sig;
2821 LLVMCallInfo *linfo = ctx->linfo;
2825 LLVMBuilderRef old_builder = ctx->builder;
2826 ctx->builder = builder;
2828 ctx->alloca_builder = create_builder (ctx);
2831 * Handle indirect/volatile variables by allocating memory for them
2832 * using 'alloca', and storing their address in a temporary.
2834 for (i = 0; i < cfg->num_varinfo; ++i) {
2835 MonoInst *var = cfg->varinfo [i];
2838 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2839 } 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))) {
2840 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2843 /* Could be already created by an OP_VPHI */
2844 if (!ctx->addresses [var->dreg]) {
2845 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2846 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2848 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2852 names = g_new (char *, sig->param_count);
2853 mono_method_get_param_names (cfg->method, (const char **) names);
2855 for (i = 0; i < sig->param_count; ++i) {
2856 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2857 int reg = cfg->args [i + sig->hasthis]->dreg;
2860 pindex = ainfo->pindex;
2862 switch (ainfo->storage) {
2863 case LLVMArgVtypeInReg:
2864 case LLVMArgAsFpArgs: {
2865 LLVMValueRef args [8];
2868 pindex += ainfo->ndummy_fpargs;
2870 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2871 memset (args, 0, sizeof (args));
2872 if (ainfo->storage == LLVMArgVtypeInReg) {
2873 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2874 if (ainfo->pair_storage [1] != LLVMArgNone)
2875 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2877 g_assert (ainfo->nslots <= 8);
2878 for (j = 0; j < ainfo->nslots; ++j)
2879 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2881 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2883 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2885 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2886 /* Treat these as normal values */
2887 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2891 case LLVMArgVtypeByVal: {
2892 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2894 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2895 /* Treat these as normal values */
2896 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2900 case LLVMArgVtypeByRef: {
2901 /* The argument is passed by ref */
2902 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2905 case LLVMArgScalarByRef: {
2907 name = g_strdup_printf ("arg_%s", names [i]);
2909 name = g_strdup_printf ("arg_%d", i);
2910 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2914 case LLVMArgAsIArgs: {
2915 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2918 /* The argument is received as an array of ints, store it into the real argument */
2919 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2921 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2922 if (size < SIZEOF_VOID_P) {
2923 /* The upper bits of the registers might not be valid */
2924 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2925 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2926 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2928 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2932 case LLVMArgVtypeAsScalar:
2933 g_assert_not_reached ();
2935 case LLVMArgGsharedvtFixed: {
2936 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2937 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2940 name = g_strdup_printf ("arg_%s", names [i]);
2942 name = g_strdup_printf ("arg_%d", i);
2944 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2947 case LLVMArgGsharedvtFixedVtype: {
2948 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2951 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2953 name = g_strdup_printf ("vtype_arg_%d", i);
2955 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2956 g_assert (ctx->addresses [reg]);
2957 LLVMSetValueName (ctx->addresses [reg], name);
2958 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2961 case LLVMArgGsharedvtVariable:
2962 /* The IR treats these as variables with addresses */
2963 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2966 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));
2973 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2975 emit_volatile_store (ctx, cfg->args [0]->dreg);
2976 for (i = 0; i < sig->param_count; ++i)
2977 if (!mini_type_is_vtype (sig->params [i]))
2978 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2980 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2981 LLVMValueRef this_alloc;
2984 * The exception handling code needs the location where the this argument was
2985 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2986 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2987 * location into the LSDA.
2989 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2990 /* This volatile store will keep the alloca alive */
2991 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2993 set_metadata_flag (this_alloc, "mono.this");
2996 if (cfg->rgctx_var) {
2997 LLVMValueRef rgctx_alloc, store;
3000 * We handle the rgctx arg similarly to the this pointer.
3002 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3003 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3004 /* This volatile store will keep the alloca alive */
3005 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3007 set_metadata_flag (rgctx_alloc, "mono.this");
3010 /* Initialize the method if needed */
3011 if (cfg->compile_aot && ctx->llvm_only) {
3012 /* Emit a location for the initialization code */
3013 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3014 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3016 LLVMBuildBr (ctx->builder, ctx->init_bb);
3017 builder = ctx->builder = create_builder (ctx);
3018 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3019 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3022 /* Compute nesting between clauses */
3023 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3024 for (i = 0; i < cfg->header->num_clauses; ++i) {
3025 for (j = 0; j < cfg->header->num_clauses; ++j) {
3026 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3027 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3029 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3030 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3035 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3036 * it needs to continue normally, or return back to the exception handling system.
3038 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3042 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3045 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3046 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3047 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3049 if (bb->in_scount == 0) {
3052 sprintf (name, "finally_ind_bb%d", bb->block_num);
3053 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3054 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3056 ctx->bblocks [bb->block_num].finally_ind = val;
3058 /* Create a variable to hold the exception var */
3060 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3064 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3065 * LLVM bblock containing a landing pad causes problems for the
3066 * LLVM optimizer passes.
3068 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3069 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3071 ctx->builder = old_builder;
3075 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3077 MonoCompile *cfg = ctx->cfg;
3078 LLVMModuleRef lmodule = ctx->lmodule;
3079 LLVMValueRef *values = ctx->values;
3080 LLVMValueRef *addresses = ctx->addresses;
3081 MonoCallInst *call = (MonoCallInst*)ins;
3082 MonoMethodSignature *sig = call->signature;
3083 LLVMValueRef callee = NULL, lcall;
3085 LLVMCallInfo *cinfo;
3089 LLVMTypeRef llvm_sig;
3091 gboolean is_virtual, calli, preserveall;
3092 LLVMBuilderRef builder = *builder_ref;
3094 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3095 set_failure (ctx, "non-default callconv");
3099 cinfo = call->cinfo;
3101 if (call->rgctx_arg_reg)
3102 cinfo->rgctx_arg = TRUE;
3103 if (call->imt_arg_reg)
3104 cinfo->imt_arg = TRUE;
3106 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);
3108 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3112 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);
3113 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);
3115 preserveall = FALSE;
3117 /* FIXME: Avoid creating duplicate methods */
3119 if (ins->flags & MONO_INST_HAS_METHOD) {
3123 if (cfg->compile_aot) {
3124 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3126 set_failure (ctx, "can't encode patch");
3129 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3131 * Collect instructions representing the callee into a hash so they can be replaced
3132 * by the llvm method for the callee if the callee turns out to be direct
3133 * callable. Currently this only requires it to not fail llvm compilation.
3135 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3136 l = g_slist_prepend (l, callee);
3137 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3140 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3143 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3145 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3149 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3150 /* LLVM miscompiles async methods */
3151 set_failure (ctx, "#13734");
3156 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3162 memset (&ji, 0, sizeof (ji));
3163 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3164 ji.data.target = info->name;
3166 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3168 if (cfg->compile_aot) {
3169 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3171 set_failure (ctx, "can't encode patch");
3175 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3176 target = (gpointer)mono_icall_get_wrapper (info);
3177 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3180 if (cfg->compile_aot) {
3182 if (cfg->abs_patches) {
3183 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3185 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3187 set_failure (ctx, "can't encode patch");
3193 set_failure (ctx, "aot");
3197 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3199 if (cfg->abs_patches) {
3200 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3203 * FIXME: Some trampolines might have
3204 * their own calling convention on some platforms.
3206 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3207 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3211 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3217 int size = sizeof (gpointer);
3220 g_assert (ins->inst_offset % size == 0);
3221 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3223 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3225 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3227 if (ins->flags & MONO_INST_HAS_METHOD) {
3232 * Collect and convert arguments
3234 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3235 len = sizeof (LLVMValueRef) * nargs;
3236 args = (LLVMValueRef*)alloca (len);
3237 memset (args, 0, len);
3238 l = call->out_ireg_args;
3240 if (call->rgctx_arg_reg) {
3241 g_assert (values [call->rgctx_arg_reg]);
3242 g_assert (cinfo->rgctx_arg_pindex < nargs);
3244 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3245 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3246 * it using a volatile load.
3249 if (!ctx->imt_rgctx_loc)
3250 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3251 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3252 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3254 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3257 if (call->imt_arg_reg) {
3258 g_assert (!ctx->llvm_only);
3259 g_assert (values [call->imt_arg_reg]);
3260 g_assert (cinfo->imt_arg_pindex < nargs);
3262 if (!ctx->imt_rgctx_loc)
3263 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3264 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3265 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3267 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3270 switch (cinfo->ret.storage) {
3271 case LLVMArgGsharedvtVariable: {
3272 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3274 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3275 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3277 g_assert (addresses [call->inst.dreg]);
3278 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3284 if (!addresses [call->inst.dreg])
3285 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3286 g_assert (cinfo->vret_arg_pindex < nargs);
3287 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3288 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3290 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3296 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3297 * use the real callee for argument type conversion.
3299 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3300 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3301 LLVMGetParamTypes (callee_type, param_types);
3303 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3306 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3308 pindex = ainfo->pindex;
3310 regpair = (guint32)(gssize)(l->data);
3311 reg = regpair & 0xffffff;
3312 args [pindex] = values [reg];
3313 switch (ainfo->storage) {
3314 case LLVMArgVtypeInReg:
3315 case LLVMArgAsFpArgs: {
3319 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3320 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3321 pindex += ainfo->ndummy_fpargs;
3323 g_assert (addresses [reg]);
3324 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3328 // FIXME: Get rid of the VMOVE
3331 case LLVMArgVtypeByVal:
3332 g_assert (addresses [reg]);
3333 args [pindex] = addresses [reg];
3335 case LLVMArgVtypeByRef:
3336 case LLVMArgScalarByRef: {
3337 g_assert (addresses [reg]);
3338 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3341 case LLVMArgAsIArgs:
3342 g_assert (addresses [reg]);
3343 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3345 case LLVMArgVtypeAsScalar:
3346 g_assert_not_reached ();
3348 case LLVMArgGsharedvtFixed:
3349 case LLVMArgGsharedvtFixedVtype:
3350 g_assert (addresses [reg]);
3351 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3353 case LLVMArgGsharedvtVariable:
3354 g_assert (addresses [reg]);
3355 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3358 g_assert (args [pindex]);
3359 if (i == 0 && sig->hasthis)
3360 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3362 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3365 g_assert (pindex <= nargs);
3370 // FIXME: Align call sites
3376 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3379 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3381 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3382 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3384 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3385 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3386 if (!sig->pinvoke && !cfg->llvm_only)
3387 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3389 mono_llvm_set_call_preserveall_cc (lcall);
3391 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3392 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3393 if (!ctx->llvm_only && call->rgctx_arg_reg)
3394 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3395 if (call->imt_arg_reg)
3396 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3398 /* Add byval attributes if needed */
3399 for (i = 0; i < sig->param_count; ++i) {
3400 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3402 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3403 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3407 * Convert the result
3409 switch (cinfo->ret.storage) {
3410 case LLVMArgVtypeInReg: {
3411 LLVMValueRef regs [2];
3413 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3417 if (!addresses [ins->dreg])
3418 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3420 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3421 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3422 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3423 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3426 case LLVMArgVtypeByVal:
3427 if (!addresses [call->inst.dreg])
3428 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3429 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3431 case LLVMArgFpStruct:
3432 if (!addresses [call->inst.dreg])
3433 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3434 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3436 case LLVMArgVtypeAsScalar:
3437 if (!addresses [call->inst.dreg])
3438 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3439 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3441 case LLVMArgVtypeRetAddr:
3442 case LLVMArgVtypeByRef:
3443 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3444 /* Some opcodes like STOREX_MEMBASE access these by value */
3445 g_assert (addresses [call->inst.dreg]);
3446 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3449 case LLVMArgScalarRetAddr:
3450 /* Normal scalar returned using a vtype return argument */
3451 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3453 case LLVMArgGsharedvtVariable:
3455 case LLVMArgGsharedvtFixed:
3456 case LLVMArgGsharedvtFixedVtype:
3457 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3460 if (sig->ret->type != MONO_TYPE_VOID)
3461 /* If the method returns an unsigned value, need to zext it */
3462 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));
3466 *builder_ref = ctx->builder;
3470 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3472 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3473 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3475 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3478 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3480 if (ctx->cfg->compile_aot) {
3481 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3483 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3484 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3485 mono_memory_barrier ();
3488 ctx->module->rethrow = callee;
3490 ctx->module->throw_icall = callee;
3494 LLVMValueRef args [2];
3496 args [0] = convert (ctx, exc, exc_type);
3497 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3499 LLVMBuildUnreachable (ctx->builder);
3501 ctx->builder = create_builder (ctx);
3505 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3507 MonoMethodSignature *throw_sig;
3508 LLVMValueRef callee, arg;
3509 const char *icall_name;
3511 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3512 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3515 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3516 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3517 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3518 if (ctx->cfg->compile_aot) {
3519 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3521 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3525 * LLVM doesn't push the exception argument, so we need a different
3528 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3530 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3534 mono_memory_barrier ();
3536 ctx->module->rethrow = callee;
3538 ctx->module->throw_icall = callee;
3540 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3541 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3545 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3547 const char *icall_name = "mono_llvm_resume_exception";
3548 LLVMValueRef callee = ctx->module->resume_eh;
3550 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3553 if (ctx->cfg->compile_aot) {
3554 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3556 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3557 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3558 mono_memory_barrier ();
3560 ctx->module->resume_eh = callee;
3564 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3566 LLVMBuildUnreachable (ctx->builder);
3568 ctx->builder = create_builder (ctx);
3572 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3574 const char *icall_name = "mono_llvm_clear_exception";
3576 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3577 LLVMValueRef callee = NULL;
3580 if (ctx->cfg->compile_aot) {
3581 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3583 // FIXME: This is broken.
3584 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3588 g_assert (builder && callee);
3590 return LLVMBuildCall (builder, callee, NULL, 0, "");
3594 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3596 const char *icall_name = "mono_llvm_load_exception";
3598 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3599 LLVMValueRef callee = NULL;
3602 if (ctx->cfg->compile_aot) {
3603 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3605 // FIXME: This is broken.
3606 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3610 g_assert (builder && callee);
3612 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3617 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3619 const char *icall_name = "mono_llvm_match_exception";
3621 ctx->builder = builder;
3623 const int num_args = 5;
3624 LLVMValueRef args [num_args];
3625 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3626 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3627 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3628 if (ctx->cfg->rgctx_var) {
3629 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3630 g_assert (rgctx_alloc);
3631 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3633 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3636 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3638 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3640 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3641 LLVMValueRef callee = ctx->module->match_exc;
3644 if (ctx->cfg->compile_aot) {
3645 ctx->builder = builder;
3646 // get_callee expects ctx->builder to be the emitting builder
3647 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3649 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3650 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3651 ctx->module->match_exc = callee;
3652 mono_memory_barrier ();
3656 g_assert (builder && callee);
3658 g_assert (ctx->ex_var);
3660 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3663 // FIXME: This won't work because the code-finding makes this
3665 /*#define MONO_PERSONALITY_DEBUG*/
3667 #ifdef MONO_PERSONALITY_DEBUG
3668 static const gboolean use_debug_personality = TRUE;
3669 static const char *default_personality_name = "mono_debug_personality";
3671 static const gboolean use_debug_personality = FALSE;
3672 static const char *default_personality_name = "__gxx_personality_v0";
3676 default_cpp_lpad_exc_signature (void)
3678 static gboolean inited = FALSE;
3679 static LLVMTypeRef sig;
3682 LLVMTypeRef signature [2];
3683 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3684 signature [1] = LLVMInt32Type ();
3685 sig = LLVMStructType (signature, 2, FALSE);
3693 get_mono_personality (EmitContext *ctx)
3695 LLVMValueRef personality = NULL;
3696 static gint32 mapping_inited = FALSE;
3697 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3699 if (!use_debug_personality) {
3700 if (ctx->cfg->compile_aot) {
3701 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3702 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3703 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3704 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3707 if (ctx->cfg->compile_aot) {
3708 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3710 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3711 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3712 mono_memory_barrier ();
3716 g_assert (personality);
3720 static LLVMBasicBlockRef
3721 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3723 MonoCompile *cfg = ctx->cfg;
3724 LLVMBuilderRef old_builder = ctx->builder;
3725 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3727 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3728 ctx->builder = lpadBuilder;
3730 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3731 g_assert (handler_bb);
3733 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3734 LLVMValueRef personality = get_mono_personality (ctx);
3735 g_assert (personality);
3737 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3738 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3740 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3741 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3742 g_assert (landing_pad);
3744 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3745 LLVMAddClause (landing_pad, cast);
3747 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3748 LLVMBuilderRef resume_builder = create_builder (ctx);
3749 ctx->builder = resume_builder;
3750 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3752 emit_resume_eh (ctx, handler_bb);
3755 ctx->builder = lpadBuilder;
3756 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3758 gboolean finally_only = TRUE;
3760 MonoExceptionClause *group_cursor = group_start;
3762 for (int i = 0; i < group_size; i ++) {
3763 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3764 finally_only = FALSE;
3770 // Handle landing pad inlining
3772 if (!finally_only) {
3773 // So at each level of the exception stack we will match the exception again.
3774 // During that match, we need to compare against the handler types for the current
3775 // protected region. We send the try start and end so that we can only check against
3776 // handlers for this lexical protected region.
3777 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3779 // if returns -1, resume
3780 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3782 // else move to that target bb
3783 for (int i=0; i < group_size; i++) {
3784 MonoExceptionClause *clause = group_start + i;
3785 int clause_index = clause - cfg->header->clauses;
3786 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3787 g_assert (handler_bb);
3788 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3789 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3792 int clause_index = group_start - cfg->header->clauses;
3793 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3794 g_assert (finally_bb);
3796 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3799 ctx->builder = old_builder;
3806 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3808 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3809 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3811 // Make exception available to catch blocks
3812 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3813 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3815 g_assert (ctx->ex_var);
3816 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3818 if (bb->in_scount == 1) {
3819 MonoInst *exvar = bb->in_stack [0];
3820 g_assert (!ctx->values [exvar->dreg]);
3821 g_assert (ctx->ex_var);
3822 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3823 emit_volatile_store (ctx, exvar->dreg);
3826 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3829 LLVMBuilderRef handler_builder = create_builder (ctx);
3830 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3831 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3833 // Make the handler code end with a jump to cbb
3834 LLVMBuildBr (handler_builder, cbb);
3838 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3840 MonoCompile *cfg = ctx->cfg;
3841 LLVMValueRef *values = ctx->values;
3842 LLVMModuleRef lmodule = ctx->lmodule;
3843 BBInfo *bblocks = ctx->bblocks;
3845 LLVMValueRef personality;
3846 LLVMValueRef landing_pad;
3847 LLVMBasicBlockRef target_bb;
3849 static gint32 mapping_inited;
3850 static int ti_generator;
3853 LLVMValueRef type_info;
3857 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3859 if (cfg->compile_aot) {
3860 /* Use a dummy personality function */
3861 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3862 g_assert (personality);
3864 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3865 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3866 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3869 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3871 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3874 * Create the type info
3876 sprintf (ti_name, "type_info_%d", ti_generator);
3879 if (cfg->compile_aot) {
3880 /* decode_eh_frame () in aot-runtime.c will decode this */
3881 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3882 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3885 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3887 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3890 * After the cfg mempool is freed, the type info will point to stale memory,
3891 * but this is not a problem, since we decode it once in exception_cb during
3894 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3895 *(gint32*)ti = clause_index;
3897 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3899 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3903 LLVMTypeRef members [2], ret_type;
3905 members [0] = i8ptr;
3906 members [1] = LLVMInt32Type ();
3907 ret_type = LLVMStructType (members, 2, FALSE);
3909 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3910 LLVMAddClause (landing_pad, type_info);
3912 /* Store the exception into the exvar */
3914 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3918 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3919 * code expects control to be transferred to this landing pad even in the
3920 * presence of nested clauses. The landing pad needs to branch to the landing
3921 * pads belonging to nested clauses based on the selector value returned by
3922 * the landing pad instruction, which is passed to the landing pad in a
3923 * register by the EH code.
3925 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3926 g_assert (target_bb);
3929 * Branch to the correct landing pad
3931 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3932 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3934 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3935 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3936 MonoBasicBlock *handler_bb;
3938 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3939 g_assert (handler_bb);
3941 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3942 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3945 /* Start a new bblock which CALL_HANDLER can branch to */
3946 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3948 ctx->builder = builder = create_builder (ctx);
3949 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3951 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3953 /* Store the exception into the IL level exvar */
3954 if (bb->in_scount == 1) {
3955 g_assert (bb->in_scount == 1);
3956 exvar = bb->in_stack [0];
3958 // FIXME: This is shared with filter clauses ?
3959 g_assert (!values [exvar->dreg]);
3961 g_assert (ctx->ex_var);
3962 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3963 emit_volatile_store (ctx, exvar->dreg);
3969 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3971 MonoCompile *cfg = ctx->cfg;
3972 MonoMethodSignature *sig = ctx->sig;
3973 LLVMValueRef method = ctx->lmethod;
3974 LLVMValueRef *values = ctx->values;
3975 LLVMValueRef *addresses = ctx->addresses;
3976 LLVMCallInfo *linfo = ctx->linfo;
3977 LLVMModuleRef lmodule = ctx->lmodule;
3978 BBInfo *bblocks = ctx->bblocks;
3980 LLVMBasicBlockRef cbb;
3981 LLVMBuilderRef builder, starting_builder;
3982 gboolean has_terminator;
3984 LLVMValueRef lhs, rhs;
3987 cbb = get_end_bb (ctx, bb);
3989 builder = create_builder (ctx);
3990 ctx->builder = builder;
3991 LLVMPositionBuilderAtEnd (builder, cbb);
3996 if (bb->flags & BB_EXCEPTION_HANDLER) {
3997 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3998 set_failure (ctx, "handler without invokes");
4003 emit_llvmonly_handler_start (ctx, bb, cbb);
4005 emit_handler_start (ctx, bb, builder);
4008 builder = ctx->builder;
4011 has_terminator = FALSE;
4012 starting_builder = builder;
4013 for (ins = bb->code; ins; ins = ins->next) {
4014 const char *spec = LLVM_INS_INFO (ins->opcode);
4016 char dname_buf [128];
4018 emit_dbg_loc (ctx, builder, ins->cil_code);
4023 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4024 * Start a new bblock. If the llvm optimization passes merge these, we
4025 * can work around that by doing a volatile load + cond branch from
4026 * localloc-ed memory.
4028 //set_failure (ctx, "basic block too long");
4029 cbb = gen_bb (ctx, "CONT_LONG_BB");
4030 LLVMBuildBr (ctx->builder, cbb);
4031 ctx->builder = builder = create_builder (ctx);
4032 LLVMPositionBuilderAtEnd (builder, cbb);
4033 ctx->bblocks [bb->block_num].end_bblock = cbb;
4038 /* There could be instructions after a terminator, skip them */
4041 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4042 sprintf (dname_buf, "t%d", ins->dreg);
4046 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4047 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4049 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4050 lhs = emit_volatile_load (ctx, ins->sreg1);
4052 /* It is ok for SETRET to have an uninitialized argument */
4053 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4054 set_failure (ctx, "sreg1");
4057 lhs = values [ins->sreg1];
4063 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4064 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4065 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4066 rhs = emit_volatile_load (ctx, ins->sreg2);
4068 if (!values [ins->sreg2]) {
4069 set_failure (ctx, "sreg2");
4072 rhs = values [ins->sreg2];
4078 //mono_print_ins (ins);
4079 switch (ins->opcode) {
4082 case OP_LIVERANGE_START:
4083 case OP_LIVERANGE_END:
4086 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4089 #if SIZEOF_VOID_P == 4
4090 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4092 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4096 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4100 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4102 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4104 case OP_DUMMY_ICONST:
4105 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4107 case OP_DUMMY_I8CONST:
4108 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4110 case OP_DUMMY_R8CONST:
4111 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4114 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4115 LLVMBuildBr (builder, target_bb);
4116 has_terminator = TRUE;
4123 LLVMBasicBlockRef new_bb;
4124 LLVMBuilderRef new_builder;
4126 // The default branch is already handled
4127 // FIXME: Handle it here
4129 /* Start new bblock */
4130 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4131 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4133 lhs = convert (ctx, lhs, LLVMInt32Type ());
4134 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4135 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4136 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4138 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4141 new_builder = create_builder (ctx);
4142 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4143 LLVMBuildUnreachable (new_builder);
4145 has_terminator = TRUE;
4146 g_assert (!ins->next);
4152 switch (linfo->ret.storage) {
4153 case LLVMArgVtypeInReg: {
4154 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4155 LLVMValueRef val, addr, retval;
4158 retval = LLVMGetUndef (ret_type);
4160 if (!addresses [ins->sreg1]) {
4162 * The return type is an LLVM vector type, have to convert between it and the
4163 * real return type which is a struct type.
4165 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4166 /* Convert to 2xi64 first */
4167 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4169 for (i = 0; i < 2; ++i) {
4170 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4171 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4173 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4177 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4178 for (i = 0; i < 2; ++i) {
4179 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4180 LLVMValueRef indexes [2], part_addr;
4182 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4183 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4184 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4186 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4188 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4192 LLVMBuildRet (builder, retval);
4195 case LLVMArgVtypeAsScalar: {
4196 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4197 LLVMValueRef retval;
4199 g_assert (addresses [ins->sreg1]);
4201 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4202 LLVMBuildRet (builder, retval);
4205 case LLVMArgVtypeByVal: {
4206 LLVMValueRef retval;
4208 g_assert (addresses [ins->sreg1]);
4209 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4210 LLVMBuildRet (builder, retval);
4213 case LLVMArgVtypeByRef: {
4214 LLVMBuildRetVoid (builder);
4217 case LLVMArgGsharedvtFixed: {
4218 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4219 /* The return value is in lhs, need to store to the vret argument */
4220 /* sreg1 might not be set */
4222 g_assert (cfg->vret_addr);
4223 g_assert (values [cfg->vret_addr->dreg]);
4224 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4226 LLVMBuildRetVoid (builder);
4229 case LLVMArgGsharedvtFixedVtype: {
4231 LLVMBuildRetVoid (builder);
4234 case LLVMArgGsharedvtVariable: {
4236 LLVMBuildRetVoid (builder);
4239 case LLVMArgVtypeRetAddr: {
4240 LLVMBuildRetVoid (builder);
4243 case LLVMArgScalarRetAddr: {
4244 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4245 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4247 /* sreg1 might not be set */
4249 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4250 LLVMBuildRetVoid (builder);
4253 case LLVMArgFpStruct: {
4254 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4255 LLVMValueRef retval;
4257 g_assert (addresses [ins->sreg1]);
4258 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4259 LLVMBuildRet (builder, retval);
4263 case LLVMArgNormal: {
4264 if (!lhs || ctx->is_dead [ins->sreg1]) {
4266 * The method did not set its return value, probably because it
4267 * ends with a throw.
4270 LLVMBuildRetVoid (builder);
4272 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4274 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4276 has_terminator = TRUE;
4280 g_assert_not_reached ();
4289 case OP_ICOMPARE_IMM:
4290 case OP_LCOMPARE_IMM:
4291 case OP_COMPARE_IMM: {
4293 LLVMValueRef cmp, args [16];
4294 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4296 if (ins->next->opcode == OP_NOP)
4299 if (ins->next->opcode == OP_BR)
4300 /* The comparison result is not needed */
4303 rel = mono_opcode_to_cond (ins->next->opcode);
4305 if (ins->opcode == OP_ICOMPARE_IMM) {
4306 lhs = convert (ctx, lhs, LLVMInt32Type ());
4307 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4309 if (ins->opcode == OP_LCOMPARE_IMM) {
4310 lhs = convert (ctx, lhs, LLVMInt64Type ());
4311 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4313 if (ins->opcode == OP_LCOMPARE) {
4314 lhs = convert (ctx, lhs, LLVMInt64Type ());
4315 rhs = convert (ctx, rhs, LLVMInt64Type ());
4317 if (ins->opcode == OP_ICOMPARE) {
4318 lhs = convert (ctx, lhs, LLVMInt32Type ());
4319 rhs = convert (ctx, rhs, LLVMInt32Type ());
4323 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4324 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4325 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4326 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4329 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4330 if (ins->opcode == OP_FCOMPARE) {
4331 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4332 } else if (ins->opcode == OP_RCOMPARE) {
4333 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4334 } else if (ins->opcode == OP_COMPARE_IMM) {
4335 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4336 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4338 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4339 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4340 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4341 /* The immediate is encoded in two fields */
4342 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4343 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4345 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4348 else if (ins->opcode == OP_COMPARE) {
4349 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4350 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4352 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4354 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4358 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4359 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4362 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4363 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4365 * If the target bb contains PHI instructions, LLVM requires
4366 * two PHI entries for this bblock, while we only generate one.
4367 * So convert this to an unconditional bblock. (bxc #171).
4369 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4371 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4373 has_terminator = TRUE;
4374 } else if (MONO_IS_SETCC (ins->next)) {
4375 sprintf (dname_buf, "t%d", ins->next->dreg);
4377 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4379 /* Add stores for volatile variables */
4380 emit_volatile_store (ctx, ins->next->dreg);
4381 } else if (MONO_IS_COND_EXC (ins->next)) {
4382 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4385 builder = ctx->builder;
4387 set_failure (ctx, "next");
4405 rel = mono_opcode_to_cond (ins->opcode);
4407 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4408 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4419 rel = mono_opcode_to_cond (ins->opcode);
4421 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4422 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4430 gboolean empty = TRUE;
4432 /* Check that all input bblocks really branch to us */
4433 for (i = 0; i < bb->in_count; ++i) {
4434 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4435 ins->inst_phi_args [i + 1] = -1;
4441 /* LLVM doesn't like phi instructions with zero operands */
4442 ctx->is_dead [ins->dreg] = TRUE;
4446 /* Created earlier, insert it now */
4447 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4449 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4450 int sreg1 = ins->inst_phi_args [i + 1];
4454 * Count the number of times the incoming bblock branches to us,
4455 * since llvm requires a separate entry for each.
4457 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4458 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4461 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4462 if (switch_ins->inst_many_bb [j] == bb)
4469 /* Remember for later */
4470 for (j = 0; j < count; ++j) {
4471 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4474 node->in_bb = bb->in_bb [i];
4476 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);
4486 values [ins->dreg] = lhs;
4490 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4493 values [ins->dreg] = lhs;
4495 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4497 * This is added by the spilling pass in case of the JIT,
4498 * but we have to do it ourselves.
4500 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4504 case OP_MOVE_F_TO_I4: {
4505 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4508 case OP_MOVE_I4_TO_F: {
4509 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4512 case OP_MOVE_F_TO_I8: {
4513 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4516 case OP_MOVE_I8_TO_F: {
4517 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4550 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4551 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4553 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4556 builder = ctx->builder;
4558 switch (ins->opcode) {
4561 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4565 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4569 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4573 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4577 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4581 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4585 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4589 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4593 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4597 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4601 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4605 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4609 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4613 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4617 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4620 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4623 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4627 g_assert_not_reached ();
4634 lhs = convert (ctx, lhs, LLVMFloatType ());
4635 rhs = convert (ctx, rhs, LLVMFloatType ());
4636 switch (ins->opcode) {
4638 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4641 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4644 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4647 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4650 g_assert_not_reached ();
4659 case OP_IREM_UN_IMM:
4661 case OP_IDIV_UN_IMM:
4667 case OP_ISHR_UN_IMM:
4677 case OP_LSHR_UN_IMM:
4683 case OP_SHR_UN_IMM: {
4686 if (spec [MONO_INST_SRC1] == 'l') {
4687 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4689 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4692 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4695 builder = ctx->builder;
4697 #if SIZEOF_VOID_P == 4
4698 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4699 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4702 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4703 lhs = convert (ctx, lhs, IntPtrType ());
4704 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4705 switch (ins->opcode) {
4709 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4713 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4718 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4722 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4724 case OP_IDIV_UN_IMM:
4725 case OP_LDIV_UN_IMM:
4726 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4730 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4732 case OP_IREM_UN_IMM:
4733 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4738 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4742 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4746 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4751 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4756 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4758 case OP_ISHR_UN_IMM:
4759 /* This is used to implement conv.u4, so the lhs could be an i8 */
4760 lhs = convert (ctx, lhs, LLVMInt32Type ());
4761 imm = convert (ctx, imm, LLVMInt32Type ());
4762 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4764 case OP_LSHR_UN_IMM:
4766 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4769 g_assert_not_reached ();
4774 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4777 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4780 lhs = convert (ctx, lhs, LLVMDoubleType ());
4781 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4784 lhs = convert (ctx, lhs, LLVMFloatType ());
4785 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4788 guint32 v = 0xffffffff;
4789 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4793 guint64 v = 0xffffffffffffffffLL;
4794 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4797 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4799 LLVMValueRef v1, v2;
4801 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4802 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4803 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4808 case OP_ICONV_TO_I1:
4809 case OP_ICONV_TO_I2:
4810 case OP_ICONV_TO_I4:
4811 case OP_ICONV_TO_U1:
4812 case OP_ICONV_TO_U2:
4813 case OP_ICONV_TO_U4:
4814 case OP_LCONV_TO_I1:
4815 case OP_LCONV_TO_I2:
4816 case OP_LCONV_TO_U1:
4817 case OP_LCONV_TO_U2:
4818 case OP_LCONV_TO_U4: {
4821 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);
4823 /* Have to do two casts since our vregs have type int */
4824 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4826 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4828 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4831 case OP_ICONV_TO_I8:
4832 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4834 case OP_ICONV_TO_U8:
4835 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4837 case OP_FCONV_TO_I4:
4838 case OP_RCONV_TO_I4:
4839 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4841 case OP_FCONV_TO_I1:
4842 case OP_RCONV_TO_I1:
4843 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4845 case OP_FCONV_TO_U1:
4846 case OP_RCONV_TO_U1:
4847 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4849 case OP_FCONV_TO_I2:
4850 case OP_RCONV_TO_I2:
4851 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4853 case OP_FCONV_TO_U2:
4854 case OP_RCONV_TO_U2:
4855 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4857 case OP_RCONV_TO_U4:
4858 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4860 case OP_FCONV_TO_I8:
4861 case OP_RCONV_TO_I8:
4862 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4865 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4867 case OP_ICONV_TO_R8:
4868 case OP_LCONV_TO_R8:
4869 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4871 case OP_ICONV_TO_R_UN:
4872 case OP_LCONV_TO_R_UN:
4873 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4875 #if SIZEOF_VOID_P == 4
4878 case OP_LCONV_TO_I4:
4879 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4881 case OP_ICONV_TO_R4:
4882 case OP_LCONV_TO_R4:
4883 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4885 values [ins->dreg] = v;
4887 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4889 case OP_FCONV_TO_R4:
4890 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4892 values [ins->dreg] = v;
4894 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4896 case OP_RCONV_TO_R8:
4897 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4899 case OP_RCONV_TO_R4:
4900 values [ins->dreg] = lhs;
4903 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4906 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4909 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4911 case OP_LOCALLOC_IMM: {
4914 guint32 size = ins->inst_imm;
4915 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4917 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4919 if (ins->flags & MONO_INST_INIT) {
4920 LLVMValueRef args [5];
4923 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4924 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4925 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4926 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4927 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4930 values [ins->dreg] = v;
4934 LLVMValueRef v, size;
4936 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), "");
4938 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4940 if (ins->flags & MONO_INST_INIT) {
4941 LLVMValueRef args [5];
4944 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4946 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4947 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4948 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4950 values [ins->dreg] = v;
4954 case OP_LOADI1_MEMBASE:
4955 case OP_LOADU1_MEMBASE:
4956 case OP_LOADI2_MEMBASE:
4957 case OP_LOADU2_MEMBASE:
4958 case OP_LOADI4_MEMBASE:
4959 case OP_LOADU4_MEMBASE:
4960 case OP_LOADI8_MEMBASE:
4961 case OP_LOADR4_MEMBASE:
4962 case OP_LOADR8_MEMBASE:
4963 case OP_LOAD_MEMBASE:
4971 LLVMValueRef base, index, addr;
4973 gboolean sext = FALSE, zext = FALSE;
4974 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4976 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4981 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)) {
4982 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4987 if (ins->inst_offset == 0) {
4989 } else if (ins->inst_offset % size != 0) {
4990 /* Unaligned load */
4991 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4992 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4994 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4995 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4999 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5001 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5003 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5005 * These will signal LLVM that these loads do not alias any stores, and
5006 * they can't fail, allowing them to be hoisted out of loops.
5008 set_invariant_load_flag (values [ins->dreg]);
5009 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5013 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5015 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5016 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5017 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5021 case OP_STOREI1_MEMBASE_REG:
5022 case OP_STOREI2_MEMBASE_REG:
5023 case OP_STOREI4_MEMBASE_REG:
5024 case OP_STOREI8_MEMBASE_REG:
5025 case OP_STORER4_MEMBASE_REG:
5026 case OP_STORER8_MEMBASE_REG:
5027 case OP_STORE_MEMBASE_REG: {
5029 LLVMValueRef index, addr;
5031 gboolean sext = FALSE, zext = FALSE;
5032 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5034 if (!values [ins->inst_destbasereg]) {
5035 set_failure (ctx, "inst_destbasereg");
5039 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5041 if (ins->inst_offset % size != 0) {
5042 /* Unaligned store */
5043 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5044 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5046 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5047 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5049 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5053 case OP_STOREI1_MEMBASE_IMM:
5054 case OP_STOREI2_MEMBASE_IMM:
5055 case OP_STOREI4_MEMBASE_IMM:
5056 case OP_STOREI8_MEMBASE_IMM:
5057 case OP_STORE_MEMBASE_IMM: {
5059 LLVMValueRef index, addr;
5061 gboolean sext = FALSE, zext = FALSE;
5062 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5064 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5066 if (ins->inst_offset % size != 0) {
5067 /* Unaligned store */
5068 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5069 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5071 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5072 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5074 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5079 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5081 case OP_OUTARG_VTRETADDR:
5089 case OP_VOIDCALL_MEMBASE:
5090 case OP_CALL_MEMBASE:
5091 case OP_LCALL_MEMBASE:
5092 case OP_FCALL_MEMBASE:
5093 case OP_RCALL_MEMBASE:
5094 case OP_VCALL_MEMBASE:
5095 case OP_VOIDCALL_REG:
5100 case OP_VCALL_REG: {
5101 process_call (ctx, bb, &builder, ins);
5106 LLVMValueRef indexes [2];
5107 MonoJumpInfo *tmp_ji, *ji;
5108 LLVMValueRef got_entry_addr;
5112 * FIXME: Can't allocate from the cfg mempool since that is freed if
5113 * the LLVM compile fails.
5115 tmp_ji = g_new0 (MonoJumpInfo, 1);
5116 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5117 tmp_ji->data.target = ins->inst_p0;
5119 ji = mono_aot_patch_info_dup (tmp_ji);
5122 ji->next = cfg->patch_info;
5123 cfg->patch_info = ji;
5125 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5126 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5127 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5128 if (!mono_aot_is_shared_got_offset (got_offset)) {
5129 //mono_print_ji (ji);
5131 ctx->has_got_access = TRUE;
5134 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5135 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5136 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5138 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5139 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5141 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5142 if (!cfg->llvm_only)
5143 set_invariant_load_flag (values [ins->dreg]);
5146 case OP_NOT_REACHED:
5147 LLVMBuildUnreachable (builder);
5148 has_terminator = TRUE;
5149 g_assert (bb->block_num < cfg->max_block_num);
5150 ctx->unreachable [bb->block_num] = TRUE;
5151 /* Might have instructions after this */
5153 MonoInst *next = ins->next;
5155 * FIXME: If later code uses the regs defined by these instructions,
5156 * compilation will fail.
5158 MONO_DELETE_INS (bb, next);
5162 MonoInst *var = ins->inst_i0;
5164 if (var->opcode == OP_VTARG_ADDR) {
5165 /* The variable contains the vtype address */
5166 values [ins->dreg] = values [var->dreg];
5167 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5168 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5170 values [ins->dreg] = addresses [var->dreg];
5175 LLVMValueRef args [1];
5177 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5178 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5182 LLVMValueRef args [1];
5184 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5185 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5189 LLVMValueRef args [1];
5191 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5192 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5196 LLVMValueRef args [1];
5198 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5199 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5213 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5214 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5216 switch (ins->opcode) {
5219 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5223 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5227 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5231 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5234 g_assert_not_reached ();
5237 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5240 case OP_ATOMIC_EXCHANGE_I4:
5241 case OP_ATOMIC_EXCHANGE_I8: {
5242 LLVMValueRef args [2];
5245 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5246 t = LLVMInt32Type ();
5248 t = LLVMInt64Type ();
5250 g_assert (ins->inst_offset == 0);
5252 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5253 args [1] = convert (ctx, rhs, t);
5255 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5258 case OP_ATOMIC_ADD_I4:
5259 case OP_ATOMIC_ADD_I8: {
5260 LLVMValueRef args [2];
5263 if (ins->opcode == OP_ATOMIC_ADD_I4)
5264 t = LLVMInt32Type ();
5266 t = LLVMInt64Type ();
5268 g_assert (ins->inst_offset == 0);
5270 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5271 args [1] = convert (ctx, rhs, t);
5272 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5275 case OP_ATOMIC_CAS_I4:
5276 case OP_ATOMIC_CAS_I8: {
5277 LLVMValueRef args [3], val;
5280 if (ins->opcode == OP_ATOMIC_CAS_I4)
5281 t = LLVMInt32Type ();
5283 t = LLVMInt64Type ();
5285 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5287 args [1] = convert (ctx, values [ins->sreg3], t);
5289 args [2] = convert (ctx, values [ins->sreg2], t);
5290 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5291 /* cmpxchg returns a pair */
5292 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5295 case OP_MEMORY_BARRIER: {
5296 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5299 case OP_ATOMIC_LOAD_I1:
5300 case OP_ATOMIC_LOAD_I2:
5301 case OP_ATOMIC_LOAD_I4:
5302 case OP_ATOMIC_LOAD_I8:
5303 case OP_ATOMIC_LOAD_U1:
5304 case OP_ATOMIC_LOAD_U2:
5305 case OP_ATOMIC_LOAD_U4:
5306 case OP_ATOMIC_LOAD_U8:
5307 case OP_ATOMIC_LOAD_R4:
5308 case OP_ATOMIC_LOAD_R8: {
5309 set_failure (ctx, "atomic mono.load intrinsic");
5313 gboolean sext, zext;
5315 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5316 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5317 LLVMValueRef index, addr;
5319 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5324 if (ins->inst_offset != 0) {
5325 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5326 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5331 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5333 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5336 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5338 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5342 case OP_ATOMIC_STORE_I1:
5343 case OP_ATOMIC_STORE_I2:
5344 case OP_ATOMIC_STORE_I4:
5345 case OP_ATOMIC_STORE_I8:
5346 case OP_ATOMIC_STORE_U1:
5347 case OP_ATOMIC_STORE_U2:
5348 case OP_ATOMIC_STORE_U4:
5349 case OP_ATOMIC_STORE_U8:
5350 case OP_ATOMIC_STORE_R4:
5351 case OP_ATOMIC_STORE_R8: {
5352 set_failure (ctx, "atomic mono.store intrinsic");
5356 gboolean sext, zext;
5358 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5359 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5360 LLVMValueRef index, addr, value;
5362 if (!values [ins->inst_destbasereg]) {
5363 set_failure (ctx, "inst_destbasereg");
5367 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5369 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5370 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5371 value = convert (ctx, values [ins->sreg1], t);
5373 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5377 case OP_RELAXED_NOP: {
5378 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5379 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5386 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5388 // 257 == FS segment register
5389 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5391 // 256 == GS segment register
5392 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5395 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5396 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5397 /* See mono_amd64_emit_tls_get () */
5398 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5400 // 256 == GS segment register
5401 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5402 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5404 set_failure (ctx, "opcode tls-get");
5410 case OP_TLS_GET_REG: {
5411 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5412 /* See emit_tls_get_reg () */
5413 // 256 == GS segment register
5414 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5415 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5417 set_failure (ctx, "opcode tls-get");
5423 case OP_TLS_SET_REG: {
5424 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5425 /* See emit_tls_get_reg () */
5426 // 256 == GS segment register
5427 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5428 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5430 set_failure (ctx, "opcode tls-set-reg");
5440 case OP_IADD_OVF_UN:
5442 case OP_ISUB_OVF_UN:
5444 case OP_IMUL_OVF_UN:
5445 #if SIZEOF_VOID_P == 8
5447 case OP_LADD_OVF_UN:
5449 case OP_LSUB_OVF_UN:
5451 case OP_LMUL_OVF_UN:
5454 LLVMValueRef args [2], val, ovf, func;
5456 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5457 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5458 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5460 val = LLVMBuildCall (builder, func, args, 2, "");
5461 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5462 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5463 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5466 builder = ctx->builder;
5472 * We currently model them using arrays. Promotion to local vregs is
5473 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5474 * so we always have an entry in cfg->varinfo for them.
5475 * FIXME: Is this needed ?
5478 MonoClass *klass = ins->klass;
5479 LLVMValueRef args [5];
5483 set_failure (ctx, "!klass");
5487 if (!addresses [ins->dreg])
5488 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5489 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5490 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5491 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5493 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5494 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5495 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5498 case OP_DUMMY_VZERO:
5501 case OP_STOREV_MEMBASE:
5502 case OP_LOADV_MEMBASE:
5504 MonoClass *klass = ins->klass;
5505 LLVMValueRef src = NULL, dst, args [5];
5506 gboolean done = FALSE;
5510 set_failure (ctx, "!klass");
5514 if (mini_is_gsharedvt_klass (klass)) {
5516 set_failure (ctx, "gsharedvt");
5520 switch (ins->opcode) {
5521 case OP_STOREV_MEMBASE:
5522 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5523 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5524 /* Decomposed earlier */
5525 g_assert_not_reached ();
5528 if (!addresses [ins->sreg1]) {
5530 g_assert (values [ins->sreg1]);
5531 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));
5532 LLVMBuildStore (builder, values [ins->sreg1], dst);
5535 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5536 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5539 case OP_LOADV_MEMBASE:
5540 if (!addresses [ins->dreg])
5541 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5542 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5543 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5546 if (!addresses [ins->sreg1])
5547 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5548 if (!addresses [ins->dreg])
5549 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5550 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5551 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5554 g_assert_not_reached ();
5564 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5565 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5567 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5568 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5569 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5572 case OP_LLVM_OUTARG_VT: {
5573 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5574 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5576 if (ainfo->storage == LLVMArgScalarByRef) {
5577 LLVMTypeRef argtype;
5578 LLVMValueRef loc, v;
5580 argtype = type_to_llvm_arg_type (ctx, t);
5581 loc = build_alloca_llvm_type (ctx, argtype, 0);
5582 v = convert (ctx, values [ins->sreg1], argtype);
5583 LLVMBuildStore (ctx->builder, v, loc);
5584 addresses [ins->dreg] = loc;
5585 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5586 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5588 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5589 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5591 g_assert (addresses [ins->sreg1]);
5592 addresses [ins->dreg] = addresses [ins->sreg1];
5594 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5595 if (!addresses [ins->sreg1]) {
5596 addresses [ins->sreg1] = build_alloca (ctx, t);
5597 g_assert (values [ins->sreg1]);
5599 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5600 addresses [ins->dreg] = addresses [ins->sreg1];
5602 if (!addresses [ins->sreg1]) {
5603 addresses [ins->sreg1] = build_alloca (ctx, t);
5604 g_assert (values [ins->sreg1]);
5605 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5607 addresses [ins->dreg] = addresses [ins->sreg1];
5615 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5617 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5620 case OP_LOADX_MEMBASE: {
5621 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5624 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5625 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5628 case OP_STOREX_MEMBASE: {
5629 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5632 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5633 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5640 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5644 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5650 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5654 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5658 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5662 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5665 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5668 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5671 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5675 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5686 LLVMValueRef v = NULL;
5688 switch (ins->opcode) {
5693 t = LLVMVectorType (LLVMInt32Type (), 4);
5694 rt = LLVMVectorType (LLVMFloatType (), 4);
5700 t = LLVMVectorType (LLVMInt64Type (), 2);
5701 rt = LLVMVectorType (LLVMDoubleType (), 2);
5704 t = LLVMInt32Type ();
5705 rt = LLVMInt32Type ();
5706 g_assert_not_reached ();
5709 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5710 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5711 switch (ins->opcode) {
5714 v = LLVMBuildAnd (builder, lhs, rhs, "");
5718 v = LLVMBuildOr (builder, lhs, rhs, "");
5722 v = LLVMBuildXor (builder, lhs, rhs, "");
5726 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5729 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5753 case OP_PADDB_SAT_UN:
5754 case OP_PADDW_SAT_UN:
5755 case OP_PSUBB_SAT_UN:
5756 case OP_PSUBW_SAT_UN:
5764 case OP_PMULW_HIGH_UN: {
5765 LLVMValueRef args [2];
5770 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5777 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5781 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5789 case OP_EXTRACTX_U2:
5791 case OP_EXTRACT_U1: {
5793 gboolean zext = FALSE;
5795 t = simd_op_to_llvm_type (ins->opcode);
5797 switch (ins->opcode) {
5805 case OP_EXTRACTX_U2:
5810 t = LLVMInt32Type ();
5811 g_assert_not_reached ();
5814 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5815 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5817 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5826 case OP_EXPAND_R8: {
5827 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5828 LLVMValueRef mask [16], v;
5831 for (i = 0; i < 16; ++i)
5832 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5834 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5836 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5837 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5842 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5845 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5848 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5851 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5854 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5857 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5868 case OP_EXTRACT_MASK:
5875 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5877 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5883 LLVMValueRef args [3];
5887 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5889 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5894 /* This is only used for implementing shifts by non-immediate */
5895 values [ins->dreg] = lhs;
5906 LLVMValueRef args [3];
5909 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5911 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5922 case OP_PSHLQ_REG: {
5923 LLVMValueRef args [3];
5926 args [1] = values [ins->sreg2];
5928 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5935 case OP_PSHUFLEW_LOW:
5936 case OP_PSHUFLEW_HIGH: {
5938 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5939 int i, mask_size = 0;
5940 int imask = ins->inst_c0;
5942 /* Convert the x86 shuffle mask to LLVM's */
5943 switch (ins->opcode) {
5946 mask [0] = ((imask >> 0) & 3);
5947 mask [1] = ((imask >> 2) & 3);
5948 mask [2] = ((imask >> 4) & 3) + 4;
5949 mask [3] = ((imask >> 6) & 3) + 4;
5950 v1 = values [ins->sreg1];
5951 v2 = values [ins->sreg2];
5955 mask [0] = ((imask >> 0) & 1);
5956 mask [1] = ((imask >> 1) & 1) + 2;
5957 v1 = values [ins->sreg1];
5958 v2 = values [ins->sreg2];
5960 case OP_PSHUFLEW_LOW:
5962 mask [0] = ((imask >> 0) & 3);
5963 mask [1] = ((imask >> 2) & 3);
5964 mask [2] = ((imask >> 4) & 3);
5965 mask [3] = ((imask >> 6) & 3);
5970 v1 = values [ins->sreg1];
5971 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5973 case OP_PSHUFLEW_HIGH:
5979 mask [4] = 4 + ((imask >> 0) & 3);
5980 mask [5] = 4 + ((imask >> 2) & 3);
5981 mask [6] = 4 + ((imask >> 4) & 3);
5982 mask [7] = 4 + ((imask >> 6) & 3);
5983 v1 = values [ins->sreg1];
5984 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5988 mask [0] = ((imask >> 0) & 3);
5989 mask [1] = ((imask >> 2) & 3);
5990 mask [2] = ((imask >> 4) & 3);
5991 mask [3] = ((imask >> 6) & 3);
5992 v1 = values [ins->sreg1];
5993 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5996 g_assert_not_reached ();
5998 for (i = 0; i < mask_size; ++i)
5999 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6001 values [ins->dreg] =
6002 LLVMBuildShuffleVector (builder, v1, v2,
6003 LLVMConstVector (mask_values, mask_size), dname);
6007 case OP_UNPACK_LOWB:
6008 case OP_UNPACK_LOWW:
6009 case OP_UNPACK_LOWD:
6010 case OP_UNPACK_LOWQ:
6011 case OP_UNPACK_LOWPS:
6012 case OP_UNPACK_LOWPD:
6013 case OP_UNPACK_HIGHB:
6014 case OP_UNPACK_HIGHW:
6015 case OP_UNPACK_HIGHD:
6016 case OP_UNPACK_HIGHQ:
6017 case OP_UNPACK_HIGHPS:
6018 case OP_UNPACK_HIGHPD: {
6020 LLVMValueRef mask_values [16];
6021 int i, mask_size = 0;
6022 gboolean low = FALSE;
6024 switch (ins->opcode) {
6025 case OP_UNPACK_LOWB:
6029 case OP_UNPACK_LOWW:
6033 case OP_UNPACK_LOWD:
6034 case OP_UNPACK_LOWPS:
6038 case OP_UNPACK_LOWQ:
6039 case OP_UNPACK_LOWPD:
6043 case OP_UNPACK_HIGHB:
6046 case OP_UNPACK_HIGHW:
6049 case OP_UNPACK_HIGHD:
6050 case OP_UNPACK_HIGHPS:
6053 case OP_UNPACK_HIGHQ:
6054 case OP_UNPACK_HIGHPD:
6058 g_assert_not_reached ();
6062 for (i = 0; i < (mask_size / 2); ++i) {
6064 mask [(i * 2) + 1] = mask_size + i;
6067 for (i = 0; i < (mask_size / 2); ++i) {
6068 mask [(i * 2)] = (mask_size / 2) + i;
6069 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6073 for (i = 0; i < mask_size; ++i)
6074 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6076 values [ins->dreg] =
6077 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6078 LLVMConstVector (mask_values, mask_size), dname);
6083 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6084 LLVMValueRef v, val;
6086 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6087 val = LLVMConstNull (t);
6088 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6089 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6091 values [ins->dreg] = val;
6095 case OP_DUPPS_HIGH: {
6096 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6097 LLVMValueRef v1, v2, val;
6100 if (ins->opcode == OP_DUPPS_LOW) {
6101 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6102 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6104 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6105 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6107 val = LLVMConstNull (t);
6108 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6109 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6110 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6111 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6113 values [ins->dreg] = val;
6123 * EXCEPTION HANDLING
6125 case OP_IMPLICIT_EXCEPTION:
6126 /* This marks a place where an implicit exception can happen */
6127 if (bb->region != -1)
6128 set_failure (ctx, "implicit-exception");
6132 gboolean rethrow = (ins->opcode == OP_RETHROW);
6133 if (ctx->llvm_only) {
6134 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6135 has_terminator = TRUE;
6136 ctx->unreachable [bb->block_num] = TRUE;
6138 emit_throw (ctx, bb, rethrow, lhs);
6139 builder = ctx->builder;
6143 case OP_CALL_HANDLER: {
6145 * We don't 'call' handlers, but instead simply branch to them.
6146 * The code generated by ENDFINALLY will branch back to us.
6148 LLVMBasicBlockRef noex_bb;
6150 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6152 bb_list = info->call_handler_return_bbs;
6155 * Set the indicator variable for the finally clause.
6157 lhs = info->finally_ind;
6159 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6161 /* Branch to the finally clause */
6162 LLVMBuildBr (builder, info->call_handler_target_bb);
6164 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6165 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6167 builder = ctx->builder = create_builder (ctx);
6168 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6170 bblocks [bb->block_num].end_bblock = noex_bb;
6173 case OP_START_HANDLER: {
6176 case OP_ENDFINALLY: {
6177 LLVMBasicBlockRef resume_bb;
6178 MonoBasicBlock *handler_bb;
6179 LLVMValueRef val, switch_ins, callee;
6183 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6184 g_assert (handler_bb);
6185 info = &bblocks [handler_bb->block_num];
6186 lhs = info->finally_ind;
6189 bb_list = info->call_handler_return_bbs;
6191 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6193 /* Load the finally variable */
6194 val = LLVMBuildLoad (builder, lhs, "");
6196 /* Reset the variable */
6197 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6199 /* Branch to either resume_bb, or to the bblocks in bb_list */
6200 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6202 * The other targets are added at the end to handle OP_CALL_HANDLER
6203 * opcodes processed later.
6205 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6207 builder = ctx->builder = create_builder (ctx);
6208 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6210 if (ctx->llvm_only) {
6211 emit_resume_eh (ctx, bb);
6213 if (ctx->cfg->compile_aot) {
6214 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6216 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6218 LLVMBuildCall (builder, callee, NULL, 0, "");
6219 LLVMBuildUnreachable (builder);
6222 has_terminator = TRUE;
6225 case OP_IL_SEQ_POINT:
6230 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6231 set_failure (ctx, reason);
6239 /* Convert the value to the type required by phi nodes */
6240 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6241 if (!values [ins->dreg])
6243 values [ins->dreg] = addresses [ins->dreg];
6245 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6248 /* Add stores for volatile variables */
6249 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6250 emit_volatile_store (ctx, ins->dreg);
6256 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6257 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6260 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6261 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6262 LLVMBuildRetVoid (builder);
6265 if (bb == cfg->bb_entry)
6266 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6270 * mono_llvm_check_method_supported:
6272 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6273 * compiling a method twice.
6276 mono_llvm_check_method_supported (MonoCompile *cfg)
6283 if (cfg->method->save_lmf) {
6284 cfg->exception_message = g_strdup ("lmf");
6285 cfg->disable_llvm = TRUE;
6287 if (cfg->disable_llvm)
6291 * Nested clauses where one of the clauses is a finally clause is
6292 * not supported, because LLVM can't figure out the control flow,
6293 * probably because we resume exception handling by calling our
6294 * own function instead of using the 'resume' llvm instruction.
6296 for (i = 0; i < cfg->header->num_clauses; ++i) {
6297 for (j = 0; j < cfg->header->num_clauses; ++j) {
6298 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6299 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6301 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6302 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6303 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6304 cfg->exception_message = g_strdup ("nested clauses");
6305 cfg->disable_llvm = TRUE;
6310 if (cfg->disable_llvm)
6314 if (cfg->method->dynamic) {
6315 cfg->exception_message = g_strdup ("dynamic.");
6316 cfg->disable_llvm = TRUE;
6318 if (cfg->disable_llvm)
6322 static LLVMCallInfo*
6323 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6325 LLVMCallInfo *linfo;
6328 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6332 * Gsharedvt methods have the following calling convention:
6333 * - all arguments are passed by ref, even non generic ones
6334 * - the return value is returned by ref too, using a vret
6335 * argument passed after 'this'.
6337 n = sig->param_count + sig->hasthis;
6338 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6342 linfo->args [pindex ++].storage = LLVMArgNormal;
6344 if (sig->ret->type != MONO_TYPE_VOID) {
6345 if (mini_is_gsharedvt_variable_type (sig->ret))
6346 linfo->ret.storage = LLVMArgGsharedvtVariable;
6347 else if (mini_type_is_vtype (sig->ret))
6348 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6350 linfo->ret.storage = LLVMArgGsharedvtFixed;
6351 linfo->vret_arg_index = pindex;
6353 linfo->ret.storage = LLVMArgNone;
6356 for (i = 0; i < sig->param_count; ++i) {
6357 if (sig->params [i]->byref)
6358 linfo->args [pindex].storage = LLVMArgNormal;
6359 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6360 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6361 else if (mini_type_is_vtype (sig->params [i]))
6362 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6364 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6365 linfo->args [pindex].type = sig->params [i];
6372 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6373 for (i = 0; i < sig->param_count; ++i)
6374 linfo->args [i + sig->hasthis].type = sig->params [i];
6380 emit_method_inner (EmitContext *ctx);
6383 free_ctx (EmitContext *ctx)
6387 g_free (ctx->values);
6388 g_free (ctx->addresses);
6389 g_free (ctx->vreg_types);
6390 g_free (ctx->vreg_cli_types);
6391 g_free (ctx->is_dead);
6392 g_free (ctx->unreachable);
6393 g_ptr_array_free (ctx->phi_values, TRUE);
6394 g_free (ctx->bblocks);
6395 g_hash_table_destroy (ctx->region_to_handler);
6396 g_hash_table_destroy (ctx->clause_to_handler);
6397 g_free (ctx->method_name);
6398 g_ptr_array_free (ctx->bblock_list, TRUE);
6400 for (l = ctx->builders; l; l = l->next) {
6401 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6402 LLVMDisposeBuilder (builder);
6409 * mono_llvm_emit_method:
6411 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6414 mono_llvm_emit_method (MonoCompile *cfg)
6418 gboolean is_linkonce = FALSE;
6421 /* The code below might acquire the loader lock, so use it for global locking */
6422 mono_loader_lock ();
6424 /* Used to communicate with the callbacks */
6425 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6427 ctx = g_new0 (EmitContext, 1);
6429 ctx->mempool = cfg->mempool;
6432 * This maps vregs to the LLVM instruction defining them
6434 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6436 * This maps vregs for volatile variables to the LLVM instruction defining their
6439 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6440 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6441 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6442 ctx->phi_values = g_ptr_array_sized_new (256);
6444 * This signals whenever the vreg was defined by a phi node with no input vars
6445 * (i.e. all its input bblocks end with NOT_REACHABLE).
6447 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6448 /* Whenever the bblock is unreachable */
6449 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6450 ctx->bblock_list = g_ptr_array_sized_new (256);
6452 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6453 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6454 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6455 if (cfg->compile_aot) {
6456 ctx->module = &aot_module;
6460 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6461 * linkage for them. This requires the following:
6462 * - the method needs to have a unique mangled name
6463 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6465 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6467 method_name = mono_aot_get_mangled_method_name (cfg->method);
6469 is_linkonce = FALSE;
6472 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6474 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6478 method_name = mono_aot_get_method_name (cfg);
6479 cfg->llvm_method_name = g_strdup (method_name);
6481 init_jit_module (cfg->domain);
6482 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6483 method_name = mono_method_full_name (cfg->method, TRUE);
6485 ctx->method_name = method_name;
6486 ctx->is_linkonce = is_linkonce;
6488 ctx->lmodule = ctx->module->lmodule;
6489 ctx->llvm_only = ctx->module->llvm_only;
6491 emit_method_inner (ctx);
6493 if (!ctx_ok (ctx)) {
6495 /* Need to add unused phi nodes as they can be referenced by other values */
6496 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6497 LLVMBuilderRef builder;
6499 builder = create_builder (ctx);
6500 LLVMPositionBuilderAtEnd (builder, phi_bb);
6502 for (i = 0; i < ctx->phi_values->len; ++i) {
6503 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6504 if (LLVMGetInstructionParent (v) == NULL)
6505 LLVMInsertIntoBuilder (builder, v);
6508 LLVMDeleteFunction (ctx->lmethod);
6514 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6516 mono_loader_unlock ();
6520 emit_method_inner (EmitContext *ctx)
6522 MonoCompile *cfg = ctx->cfg;
6523 MonoMethodSignature *sig;
6525 LLVMTypeRef method_type;
6526 LLVMValueRef method = NULL;
6527 LLVMValueRef *values = ctx->values;
6528 int i, max_block_num, bb_index;
6529 gboolean last = FALSE;
6530 LLVMCallInfo *linfo;
6531 LLVMModuleRef lmodule = ctx->lmodule;
6533 GPtrArray *bblock_list = ctx->bblock_list;
6534 MonoMethodHeader *header;
6535 MonoExceptionClause *clause;
6538 if (cfg->gsharedvt && !cfg->llvm_only) {
6539 set_failure (ctx, "gsharedvt");
6545 static int count = 0;
6548 if (g_getenv ("LLVM_COUNT")) {
6549 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6550 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6554 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6555 set_failure (ctx, "count");
6562 sig = mono_method_signature (cfg->method);
6565 linfo = get_llvm_call_info (cfg, sig);
6571 linfo->rgctx_arg = TRUE;
6572 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6576 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6577 ctx->lmethod = method;
6579 if (!cfg->llvm_only)
6580 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6581 LLVMSetLinkage (method, LLVMPrivateLinkage);
6583 LLVMAddFunctionAttr (method, LLVMUWTable);
6585 if (cfg->compile_aot) {
6586 LLVMSetLinkage (method, LLVMInternalLinkage);
6587 if (ctx->module->external_symbols) {
6588 LLVMSetLinkage (method, LLVMExternalLinkage);
6589 LLVMSetVisibility (method, LLVMHiddenVisibility);
6591 if (ctx->is_linkonce) {
6592 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6593 LLVMSetVisibility (method, LLVMDefaultVisibility);
6596 LLVMSetLinkage (method, LLVMPrivateLinkage);
6599 if (cfg->method->save_lmf && !cfg->llvm_only) {
6600 set_failure (ctx, "lmf");
6604 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6605 set_failure (ctx, "pinvoke signature");
6609 header = cfg->header;
6610 for (i = 0; i < header->num_clauses; ++i) {
6611 clause = &header->clauses [i];
6612 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6613 set_failure (ctx, "non-finally/catch clause.");
6617 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6618 /* We can't handle inlined methods with clauses */
6619 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6621 if (linfo->rgctx_arg) {
6622 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6623 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6625 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6626 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6627 * CC_X86_64_Mono in X86CallingConv.td.
6629 if (!ctx->llvm_only)
6630 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6631 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6633 ctx->rgctx_arg_pindex = -1;
6635 if (cfg->vret_addr) {
6636 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6637 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6638 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6639 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6640 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6642 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6643 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6644 LLVMSetValueName (param, "vret");
6648 ctx->this_arg_pindex = linfo->this_arg_pindex;
6649 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6650 values [cfg->args [0]->dreg] = ctx->this_arg;
6651 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6654 names = g_new (char *, sig->param_count);
6655 mono_method_get_param_names (cfg->method, (const char **) names);
6657 for (i = 0; i < sig->param_count; ++i) {
6658 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6660 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6663 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6664 name = g_strdup_printf ("dummy_%d_%d", i, j);
6665 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6669 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6670 if (ainfo->storage == LLVMArgScalarByRef) {
6671 if (names [i] && names [i][0] != '\0')
6672 name = g_strdup_printf ("p_arg_%s", names [i]);
6674 name = g_strdup_printf ("p_arg_%d", i);
6675 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6676 if (names [i] && names [i][0] != '\0')
6677 name = g_strdup_printf ("p_arg_%s", names [i]);
6679 name = g_strdup_printf ("p_arg_%d", i);
6681 if (names [i] && names [i][0] != '\0')
6682 name = g_strdup_printf ("arg_%s", names [i]);
6684 name = g_strdup_printf ("arg_%d", i);
6686 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6688 if (ainfo->storage == LLVMArgVtypeByVal)
6689 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6691 if (ainfo->storage == LLVMArgVtypeByRef) {
6693 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6698 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6699 ctx->minfo = mono_debug_lookup_method (cfg->method);
6700 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6704 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6705 max_block_num = MAX (max_block_num, bb->block_num);
6706 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6708 /* Add branches between non-consecutive bblocks */
6709 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6710 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6711 bb->next_bb != bb->last_ins->inst_false_bb) {
6713 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6714 inst->opcode = OP_BR;
6715 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6716 mono_bblock_add_inst (bb, inst);
6721 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6722 * was later optimized away, so clear these flags, and add them back for the still
6723 * present OP_LDADDR instructions.
6725 for (i = 0; i < cfg->next_vreg; ++i) {
6728 ins = get_vreg_to_inst (cfg, i);
6729 if (ins && ins != cfg->rgctx_var)
6730 ins->flags &= ~MONO_INST_INDIRECT;
6734 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6736 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6738 LLVMBuilderRef builder;
6740 char dname_buf[128];
6742 builder = create_builder (ctx);
6744 for (ins = bb->code; ins; ins = ins->next) {
6745 switch (ins->opcode) {
6750 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6755 if (ins->opcode == OP_VPHI) {
6756 /* Treat valuetype PHI nodes as operating on the address itself */
6757 g_assert (ins->klass);
6758 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6762 * Have to precreate these, as they can be referenced by
6763 * earlier instructions.
6765 sprintf (dname_buf, "t%d", ins->dreg);
6767 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6769 if (ins->opcode == OP_VPHI)
6770 ctx->addresses [ins->dreg] = values [ins->dreg];
6772 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6775 * Set the expected type of the incoming arguments since these have
6776 * to have the same type.
6778 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6779 int sreg1 = ins->inst_phi_args [i + 1];
6782 ctx->vreg_types [sreg1] = phi_type;
6787 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6796 * Create an ordering for bblocks, use the depth first order first, then
6797 * put the exception handling bblocks last.
6799 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6800 bb = cfg->bblocks [bb_index];
6801 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6802 g_ptr_array_add (bblock_list, bb);
6803 bblocks [bb->block_num].added = TRUE;
6807 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6808 if (!bblocks [bb->block_num].added)
6809 g_ptr_array_add (bblock_list, bb);
6813 * Second pass: generate code.
6816 LLVMBuilderRef entry_builder = create_builder (ctx);
6817 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6818 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6819 emit_entry_bb (ctx, entry_builder);
6821 // Make landing pads first
6822 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6824 if (ctx->llvm_only) {
6825 size_t group_index = 0;
6826 while (group_index < cfg->header->num_clauses) {
6828 size_t cursor = group_index;
6829 while (cursor < cfg->header->num_clauses &&
6830 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6831 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6836 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6837 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6838 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6840 group_index = cursor;
6844 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6845 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6847 // Prune unreachable mono BBs.
6848 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6851 process_bb (ctx, bb);
6855 g_hash_table_destroy (ctx->exc_meta);
6857 mono_memory_barrier ();
6859 /* Add incoming phi values */
6860 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6861 GSList *l, *ins_list;
6863 ins_list = bblocks [bb->block_num].phi_nodes;
6865 for (l = ins_list; l; l = l->next) {
6866 PhiNode *node = (PhiNode*)l->data;
6867 MonoInst *phi = node->phi;
6868 int sreg1 = node->sreg;
6869 LLVMBasicBlockRef in_bb;
6874 in_bb = get_end_bb (ctx, node->in_bb);
6876 if (ctx->unreachable [node->in_bb->block_num])
6879 if (!values [sreg1]) {
6880 /* Can happen with values in EH clauses */
6881 set_failure (ctx, "incoming phi sreg1");
6885 if (phi->opcode == OP_VPHI) {
6886 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6887 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6889 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6890 set_failure (ctx, "incoming phi arg type mismatch");
6893 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6894 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6899 /* Nullify empty phi instructions */
6900 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6901 GSList *l, *ins_list;
6903 ins_list = bblocks [bb->block_num].phi_nodes;
6905 for (l = ins_list; l; l = l->next) {
6906 PhiNode *node = (PhiNode*)l->data;
6907 MonoInst *phi = node->phi;
6908 LLVMValueRef phi_ins = values [phi->dreg];
6911 /* Already removed */
6914 if (LLVMCountIncoming (phi_ins) == 0) {
6915 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6916 LLVMInstructionEraseFromParent (phi_ins);
6917 values [phi->dreg] = NULL;
6922 /* Create the SWITCH statements for ENDFINALLY instructions */
6923 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6924 BBInfo *info = &bblocks [bb->block_num];
6926 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6927 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6928 GSList *bb_list = info->call_handler_return_bbs;
6930 for (i = 0; i < g_slist_length (bb_list); ++i)
6931 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6935 /* Initialize the method if needed */
6936 if (cfg->compile_aot && ctx->llvm_only) {
6937 // FIXME: Add more shared got entries
6938 ctx->builder = create_builder (ctx);
6939 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6941 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6943 // FIXME: beforefieldinit
6944 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6945 emit_init_method (ctx);
6947 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6951 if (cfg->llvm_only) {
6952 GHashTableIter iter;
6954 GSList *callers, *l, *l2;
6957 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6958 * We can't do this earlier, as it contains llvm instructions which can be
6959 * freed if compilation fails.
6960 * FIXME: Get rid of this when all methods can be llvm compiled.
6962 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6963 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6964 for (l = callers; l; l = l->next) {
6965 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6966 l2 = g_slist_prepend (l2, l->data);
6967 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6972 if (cfg->verbose_level > 1)
6973 mono_llvm_dump_value (method);
6975 if (cfg->compile_aot && !cfg->llvm_only)
6976 mark_as_used (ctx->module, method);
6978 if (cfg->compile_aot && !cfg->llvm_only) {
6979 LLVMValueRef md_args [16];
6980 LLVMValueRef md_node;
6983 method_index = mono_aot_get_method_index (cfg->orig_method);
6984 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6985 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6986 md_node = LLVMMDNode (md_args, 2);
6987 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6988 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6991 if (cfg->compile_aot) {
6992 /* Don't generate native code, keep the LLVM IR */
6993 if (cfg->verbose_level)
6994 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
6996 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
6997 g_assert (err == 0);
6999 //LLVMVerifyFunction(method, 0);
7000 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7002 if (cfg->verbose_level > 1)
7003 mono_llvm_dump_value (ctx->lmethod);
7005 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7007 /* Set by emit_cb */
7008 g_assert (cfg->code_len);
7011 if (ctx->module->method_to_lmethod)
7012 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7013 if (ctx->module->idx_to_lmethod)
7014 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7016 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7017 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7021 * mono_llvm_create_vars:
7023 * Same as mono_arch_create_vars () for LLVM.
7026 mono_llvm_create_vars (MonoCompile *cfg)
7028 MonoMethodSignature *sig;
7030 sig = mono_method_signature (cfg->method);
7031 if (cfg->gsharedvt && cfg->llvm_only) {
7032 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7033 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7034 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7035 printf ("vret_addr = ");
7036 mono_print_ins (cfg->vret_addr);
7040 mono_arch_create_vars (cfg);
7045 * mono_llvm_emit_call:
7047 * Same as mono_arch_emit_call () for LLVM.
7050 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7053 MonoMethodSignature *sig;
7054 int i, n, stack_size;
7059 sig = call->signature;
7060 n = sig->param_count + sig->hasthis;
7062 call->cinfo = get_llvm_call_info (cfg, sig);
7064 if (cfg->disable_llvm)
7067 if (sig->call_convention == MONO_CALL_VARARG) {
7068 cfg->exception_message = g_strdup ("varargs");
7069 cfg->disable_llvm = TRUE;
7072 for (i = 0; i < n; ++i) {
7075 ainfo = call->cinfo->args + i;
7077 in = call->args [i];
7079 /* Simply remember the arguments */
7080 switch (ainfo->storage) {
7081 case LLVMArgNormal: {
7082 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7085 opcode = mono_type_to_regmove (cfg, t);
7086 if (opcode == OP_FMOVE) {
7087 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7088 ins->dreg = mono_alloc_freg (cfg);
7089 } else if (opcode == OP_LMOVE) {
7090 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7091 ins->dreg = mono_alloc_lreg (cfg);
7092 } else if (opcode == OP_RMOVE) {
7093 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7094 ins->dreg = mono_alloc_freg (cfg);
7096 MONO_INST_NEW (cfg, ins, OP_MOVE);
7097 ins->dreg = mono_alloc_ireg (cfg);
7099 ins->sreg1 = in->dreg;
7102 case LLVMArgVtypeByVal:
7103 case LLVMArgVtypeByRef:
7104 case LLVMArgVtypeInReg:
7105 case LLVMArgVtypeAsScalar:
7106 case LLVMArgScalarByRef:
7107 case LLVMArgAsIArgs:
7108 case LLVMArgAsFpArgs:
7109 case LLVMArgGsharedvtVariable:
7110 case LLVMArgGsharedvtFixed:
7111 case LLVMArgGsharedvtFixedVtype:
7112 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7113 ins->dreg = mono_alloc_ireg (cfg);
7114 ins->sreg1 = in->dreg;
7115 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7116 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7117 ins->inst_vtype = ainfo->type;
7118 ins->klass = mono_class_from_mono_type (ainfo->type);
7121 cfg->exception_message = g_strdup ("ainfo->storage");
7122 cfg->disable_llvm = TRUE;
7126 if (!cfg->disable_llvm) {
7127 MONO_ADD_INS (cfg->cbb, ins);
7128 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7133 static unsigned char*
7134 alloc_cb (LLVMValueRef function, int size)
7138 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7142 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7144 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7149 emitted_cb (LLVMValueRef function, void *start, void *end)
7153 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7155 cfg->code_len = (guint8*)end - (guint8*)start;
7159 exception_cb (void *data)
7162 MonoJitExceptionInfo *ei;
7163 guint32 ei_len, i, j, nested_len, nindex;
7164 gpointer *type_info;
7165 int this_reg, this_offset;
7167 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7171 * data points to a DWARF FDE structure, convert it to our unwind format and
7173 * An alternative would be to save it directly, and modify our unwinder to work
7176 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);
7177 if (cfg->verbose_level > 1)
7178 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7180 /* Count nested clauses */
7182 for (i = 0; i < ei_len; ++i) {
7183 gint32 cindex1 = *(gint32*)type_info [i];
7184 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7186 for (j = 0; j < cfg->header->num_clauses; ++j) {
7188 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7190 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7196 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7197 cfg->llvm_ex_info_len = ei_len + nested_len;
7198 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7199 /* Fill the rest of the information from the type info */
7200 for (i = 0; i < ei_len; ++i) {
7201 gint32 clause_index = *(gint32*)type_info [i];
7202 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7204 cfg->llvm_ex_info [i].flags = clause->flags;
7205 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7206 cfg->llvm_ex_info [i].clause_index = clause_index;
7210 * For nested clauses, the LLVM produced exception info associates the try interval with
7211 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7212 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7213 * and everything else from the nested clause.
7216 for (i = 0; i < ei_len; ++i) {
7217 gint32 cindex1 = *(gint32*)type_info [i];
7218 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7220 for (j = 0; j < cfg->header->num_clauses; ++j) {
7222 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7223 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7225 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7226 /* clause1 is the nested clause */
7227 nested_ei = &cfg->llvm_ex_info [i];
7228 nesting_ei = &cfg->llvm_ex_info [nindex];
7231 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7233 nesting_ei->flags = clause2->flags;
7234 nesting_ei->data.catch_class = clause2->data.catch_class;
7235 nesting_ei->clause_index = cindex2;
7239 g_assert (nindex == ei_len + nested_len);
7240 cfg->llvm_this_reg = this_reg;
7241 cfg->llvm_this_offset = this_offset;
7243 /* type_info [i] is cfg mempool allocated, no need to free it */
7250 dlsym_cb (const char *name, void **symbol)
7256 if (!strcmp (name, "__bzero")) {
7257 *symbol = (void*)bzero;
7259 current = mono_dl_open (NULL, 0, NULL);
7262 err = mono_dl_symbol (current, name, symbol);
7264 mono_dl_close (current);
7266 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7267 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7273 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7275 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7279 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7281 LLVMTypeRef param_types [4];
7283 param_types [0] = param_type1;
7284 param_types [1] = param_type2;
7286 AddFunc (module, name, ret_type, param_types, 2);
7290 add_intrinsics (LLVMModuleRef module)
7292 /* Emit declarations of instrinsics */
7294 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7295 * type doesn't seem to do any locking.
7298 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7300 memset_param_count = 5;
7301 memset_func_name = "llvm.memset.p0i8.i32";
7303 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7307 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7309 memcpy_param_count = 5;
7310 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7312 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7316 LLVMTypeRef params [] = { LLVMDoubleType () };
7318 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7319 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7320 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7322 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7323 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7327 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7328 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7329 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7331 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7332 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7333 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7334 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7335 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7336 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7337 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7341 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7342 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7343 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7345 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7346 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7347 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7348 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7349 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7350 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7353 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7354 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7358 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7360 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7363 /* SSE intrinsics */
7364 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7366 LLVMTypeRef ret_type, arg_types [16];
7369 ret_type = type_to_simd_type (MONO_TYPE_I4);
7370 arg_types [0] = ret_type;
7371 arg_types [1] = ret_type;
7372 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7373 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7375 ret_type = type_to_simd_type (MONO_TYPE_I2);
7376 arg_types [0] = ret_type;
7377 arg_types [1] = ret_type;
7378 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7379 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7380 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7382 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7383 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7384 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7385 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7386 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7387 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7389 ret_type = type_to_simd_type (MONO_TYPE_I1);
7390 arg_types [0] = ret_type;
7391 arg_types [1] = ret_type;
7392 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7394 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7395 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7396 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7397 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7398 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7400 ret_type = type_to_simd_type (MONO_TYPE_R8);
7401 arg_types [0] = ret_type;
7402 arg_types [1] = ret_type;
7403 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7404 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7405 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7406 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7407 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7409 ret_type = type_to_simd_type (MONO_TYPE_R4);
7410 arg_types [0] = ret_type;
7411 arg_types [1] = ret_type;
7412 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7413 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7414 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7415 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7416 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7419 ret_type = type_to_simd_type (MONO_TYPE_I1);
7420 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7421 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7422 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7423 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7424 ret_type = type_to_simd_type (MONO_TYPE_I2);
7425 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7426 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7427 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7428 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7431 ret_type = type_to_simd_type (MONO_TYPE_R8);
7432 arg_types [0] = ret_type;
7433 arg_types [1] = ret_type;
7434 arg_types [2] = LLVMInt8Type ();
7435 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7436 ret_type = type_to_simd_type (MONO_TYPE_R4);
7437 arg_types [0] = ret_type;
7438 arg_types [1] = ret_type;
7439 arg_types [2] = LLVMInt8Type ();
7440 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7442 /* Conversion ops */
7443 ret_type = type_to_simd_type (MONO_TYPE_R8);
7444 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7445 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7446 ret_type = type_to_simd_type (MONO_TYPE_R4);
7447 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7448 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7449 ret_type = type_to_simd_type (MONO_TYPE_I4);
7450 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7451 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7452 ret_type = type_to_simd_type (MONO_TYPE_I4);
7453 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7454 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7455 ret_type = type_to_simd_type (MONO_TYPE_R4);
7456 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7457 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7458 ret_type = type_to_simd_type (MONO_TYPE_R8);
7459 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7460 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7462 ret_type = type_to_simd_type (MONO_TYPE_I4);
7463 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7464 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7465 ret_type = type_to_simd_type (MONO_TYPE_I4);
7466 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7467 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7470 ret_type = type_to_simd_type (MONO_TYPE_R8);
7471 arg_types [0] = ret_type;
7472 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7473 ret_type = type_to_simd_type (MONO_TYPE_R4);
7474 arg_types [0] = ret_type;
7475 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7476 ret_type = type_to_simd_type (MONO_TYPE_R4);
7477 arg_types [0] = ret_type;
7478 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7479 ret_type = type_to_simd_type (MONO_TYPE_R4);
7480 arg_types [0] = ret_type;
7481 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7484 ret_type = type_to_simd_type (MONO_TYPE_I2);
7485 arg_types [0] = ret_type;
7486 arg_types [1] = LLVMInt32Type ();
7487 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7488 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7489 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7490 ret_type = type_to_simd_type (MONO_TYPE_I4);
7491 arg_types [0] = ret_type;
7492 arg_types [1] = LLVMInt32Type ();
7493 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7494 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7495 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7496 ret_type = type_to_simd_type (MONO_TYPE_I8);
7497 arg_types [0] = ret_type;
7498 arg_types [1] = LLVMInt32Type ();
7499 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7500 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7503 ret_type = LLVMInt32Type ();
7504 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7505 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7508 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7511 /* Load/Store intrinsics */
7513 LLVMTypeRef arg_types [5];
7517 for (i = 1; i <= 8; i *= 2) {
7518 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7519 arg_types [1] = LLVMInt32Type ();
7520 arg_types [2] = LLVMInt1Type ();
7521 arg_types [3] = LLVMInt32Type ();
7522 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7523 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7525 arg_types [0] = LLVMIntType (i * 8);
7526 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7527 arg_types [2] = LLVMInt32Type ();
7528 arg_types [3] = LLVMInt1Type ();
7529 arg_types [4] = LLVMInt32Type ();
7530 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7531 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7537 add_types (MonoLLVMModule *module)
7539 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7543 mono_llvm_init (void)
7545 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7549 init_jit_module (MonoDomain *domain)
7551 MonoJitICallInfo *info;
7552 MonoJitDomainInfo *dinfo;
7553 MonoLLVMModule *module;
7556 dinfo = domain_jit_info (domain);
7557 if (dinfo->llvm_module)
7560 mono_loader_lock ();
7562 if (dinfo->llvm_module) {
7563 mono_loader_unlock ();
7567 module = g_new0 (MonoLLVMModule, 1);
7569 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7570 module->lmodule = LLVMModuleCreateWithName (name);
7571 module->context = LLVMGetGlobalContext ();
7573 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7575 add_intrinsics (module->lmodule);
7578 module->llvm_types = g_hash_table_new (NULL, NULL);
7580 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7582 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7584 mono_memory_barrier ();
7586 dinfo->llvm_module = module;
7588 mono_loader_unlock ();
7592 mono_llvm_cleanup (void)
7594 MonoLLVMModule *module = &aot_module;
7596 if (module->lmodule)
7597 LLVMDisposeModule (module->lmodule);
7599 if (module->context)
7600 LLVMContextDispose (module->context);
7604 mono_llvm_free_domain_info (MonoDomain *domain)
7606 MonoJitDomainInfo *info = domain_jit_info (domain);
7607 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7613 if (module->llvm_types)
7614 g_hash_table_destroy (module->llvm_types);
7616 mono_llvm_dispose_ee (module->mono_ee);
7618 if (module->bb_names) {
7619 for (i = 0; i < module->bb_names_len; ++i)
7620 g_free (module->bb_names [i]);
7621 g_free (module->bb_names);
7623 //LLVMDisposeModule (module->module);
7627 info->llvm_module = NULL;
7631 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7633 MonoLLVMModule *module = &aot_module;
7635 /* Delete previous module */
7636 if (module->plt_entries)
7637 g_hash_table_destroy (module->plt_entries);
7638 if (module->lmodule)
7639 LLVMDisposeModule (module->lmodule);
7641 memset (module, 0, sizeof (aot_module));
7643 module->lmodule = LLVMModuleCreateWithName ("aot");
7644 module->assembly = assembly;
7645 module->global_prefix = g_strdup (global_prefix);
7646 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7647 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7648 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7649 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7650 module->external_symbols = TRUE;
7651 module->emit_dwarf = emit_dwarf;
7652 module->static_link = static_link;
7653 module->llvm_only = llvm_only;
7654 /* The first few entries are reserved */
7655 module->max_got_offset = 16;
7656 module->context = LLVMContextCreate ();
7659 /* clang ignores our debug info because it has an invalid version */
7660 module->emit_dwarf = FALSE;
7662 add_intrinsics (module->lmodule);
7667 * We couldn't compute the type of the LLVM global representing the got because
7668 * its size is only known after all the methods have been emitted. So create
7669 * a dummy variable, and replace all uses it with the real got variable when
7670 * its size is known in mono_llvm_emit_aot_module ().
7673 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7675 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7676 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7679 /* Add initialization array */
7681 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7683 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7684 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7688 emit_init_icall_wrappers (module);
7690 emit_llvm_code_start (module);
7692 /* Add a dummy personality function */
7693 if (!use_debug_personality) {
7694 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7695 LLVMSetLinkage (personality, LLVMExternalLinkage);
7696 mark_as_used (module, personality);
7699 /* Add a reference to the c++ exception we throw/catch */
7701 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7702 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7703 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7704 mono_llvm_set_is_constant (module->sentinel_exception);
7707 module->llvm_types = g_hash_table_new (NULL, NULL);
7708 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7709 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7710 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7711 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7712 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7713 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7714 module->method_to_callers = g_hash_table_new (NULL, NULL);
7718 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7721 LLVMValueRef res, *vals;
7723 vals = g_new0 (LLVMValueRef, nvalues);
7724 for (i = 0; i < nvalues; ++i)
7725 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7726 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7732 * mono_llvm_emit_aot_file_info:
7734 * Emit the MonoAotFileInfo structure.
7735 * Same as emit_aot_file_info () in aot-compiler.c.
7738 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7740 MonoLLVMModule *module = &aot_module;
7742 /* Save these for later */
7743 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7744 module->has_jitted_code = has_jitted_code;
7748 * mono_llvm_emit_aot_data:
7750 * Emit the binary data DATA pointed to by symbol SYMBOL.
7753 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7755 MonoLLVMModule *module = &aot_module;
7759 type = LLVMArrayType (LLVMInt8Type (), data_len);
7760 d = LLVMAddGlobal (module->lmodule, type, symbol);
7761 LLVMSetVisibility (d, LLVMHiddenVisibility);
7762 LLVMSetLinkage (d, LLVMInternalLinkage);
7763 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7764 mono_llvm_set_is_constant (d);
7767 /* Add a reference to a global defined in JITted code */
7769 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7774 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7775 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7781 emit_aot_file_info (MonoLLVMModule *module)
7783 LLVMTypeRef file_info_type;
7784 LLVMTypeRef *eltypes, eltype;
7785 LLVMValueRef info_var;
7786 LLVMValueRef *fields;
7787 int i, nfields, tindex;
7788 MonoAotFileInfo *info;
7789 LLVMModuleRef lmodule = module->lmodule;
7791 info = &module->aot_info;
7793 /* Create an LLVM type to represent MonoAotFileInfo */
7794 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7795 eltypes = g_new (LLVMTypeRef, nfields);
7797 eltypes [tindex ++] = LLVMInt32Type ();
7798 eltypes [tindex ++] = LLVMInt32Type ();
7800 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7801 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7803 for (i = 0; i < 15; ++i)
7804 eltypes [tindex ++] = LLVMInt32Type ();
7806 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7807 for (i = 0; i < 4; ++i)
7808 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7809 g_assert (tindex == nfields);
7810 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7811 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7813 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7814 if (module->static_link) {
7815 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7816 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7818 fields = g_new (LLVMValueRef, nfields);
7820 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7821 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7825 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7826 * for symbols defined in the .s file emitted by the aot compiler.
7828 eltype = eltypes [tindex];
7829 if (module->llvm_only)
7830 fields [tindex ++] = LLVMConstNull (eltype);
7832 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7833 fields [tindex ++] = module->got_var;
7834 /* llc defines this directly */
7835 if (!module->llvm_only) {
7836 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7837 fields [tindex ++] = LLVMConstNull (eltype);
7838 fields [tindex ++] = LLVMConstNull (eltype);
7840 fields [tindex ++] = LLVMConstNull (eltype);
7841 fields [tindex ++] = module->get_method;
7842 fields [tindex ++] = module->get_unbox_tramp;
7844 if (module->has_jitted_code) {
7845 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7846 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7848 fields [tindex ++] = LLVMConstNull (eltype);
7849 fields [tindex ++] = LLVMConstNull (eltype);
7851 if (!module->llvm_only)
7852 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7854 fields [tindex ++] = LLVMConstNull (eltype);
7855 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7856 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7857 fields [tindex ++] = LLVMConstNull (eltype);
7859 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7860 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7861 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7862 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7863 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7864 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7865 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7866 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7867 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7868 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7870 /* Not needed (mem_end) */
7871 fields [tindex ++] = LLVMConstNull (eltype);
7872 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7873 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7874 if (info->trampoline_size [0]) {
7875 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7876 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7877 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7878 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7880 fields [tindex ++] = LLVMConstNull (eltype);
7881 fields [tindex ++] = LLVMConstNull (eltype);
7882 fields [tindex ++] = LLVMConstNull (eltype);
7883 fields [tindex ++] = LLVMConstNull (eltype);
7885 if (module->static_link && !module->llvm_only)
7886 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7888 fields [tindex ++] = LLVMConstNull (eltype);
7889 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7890 if (!module->llvm_only) {
7891 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7892 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7893 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7894 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7895 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7896 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7898 fields [tindex ++] = LLVMConstNull (eltype);
7899 fields [tindex ++] = LLVMConstNull (eltype);
7900 fields [tindex ++] = LLVMConstNull (eltype);
7901 fields [tindex ++] = LLVMConstNull (eltype);
7902 fields [tindex ++] = LLVMConstNull (eltype);
7903 fields [tindex ++] = LLVMConstNull (eltype);
7906 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7907 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7910 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7911 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7912 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7913 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7914 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7915 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7916 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7917 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7918 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7919 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7920 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7921 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7922 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7923 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7924 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7926 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7927 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7928 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7929 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7930 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7931 g_assert (tindex == nfields);
7933 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7935 if (module->static_link) {
7939 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7940 /* Get rid of characters which cannot occur in symbols */
7942 for (p = s; *p; ++p) {
7943 if (!(isalnum (*p) || *p == '_'))
7946 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7948 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7949 LLVMSetLinkage (var, LLVMExternalLinkage);
7954 * Emit the aot module into the LLVM bitcode file FILENAME.
7957 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7959 LLVMTypeRef got_type, inited_type;
7960 LLVMValueRef real_got, real_inited;
7961 MonoLLVMModule *module = &aot_module;
7963 emit_llvm_code_end (module);
7966 * Create the real got variable and replace all uses of the dummy variable with
7969 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7970 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7971 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7972 if (module->external_symbols) {
7973 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7974 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7976 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7978 mono_llvm_replace_uses_of (module->got_var, real_got);
7980 mark_as_used (&aot_module, real_got);
7982 /* Delete the dummy got so it doesn't become a global */
7983 LLVMDeleteGlobal (module->got_var);
7984 module->got_var = real_got;
7987 * Same for the init_var
7989 if (module->llvm_only) {
7990 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7991 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7992 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7993 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7994 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7995 LLVMDeleteGlobal (module->inited_var);
7998 if (module->llvm_only) {
7999 emit_get_method (&aot_module);
8000 emit_get_unbox_tramp (&aot_module);
8003 emit_llvm_used (&aot_module);
8004 emit_dbg_info (&aot_module, filename, cu_name);
8005 emit_aot_file_info (&aot_module);
8008 * Replace GOT entries for directly callable methods with the methods themselves.
8009 * It would be easier to implement this by predefining all methods before compiling
8010 * their bodies, but that couldn't handle the case when a method fails to compile
8013 if (module->llvm_only) {
8014 GHashTableIter iter;
8016 GSList *callers, *l;
8018 g_hash_table_iter_init (&iter, module->method_to_callers);
8019 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8020 LLVMValueRef lmethod;
8022 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8024 for (l = callers; l; l = l->next) {
8025 LLVMValueRef caller = (LLVMValueRef)l->data;
8027 mono_llvm_replace_uses_of (caller, lmethod);
8033 /* Replace PLT entries for directly callable methods with the methods themselves */
8035 GHashTableIter iter;
8037 LLVMValueRef callee;
8039 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8040 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8041 if (mono_aot_is_direct_callable (ji)) {
8042 LLVMValueRef lmethod;
8044 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8045 /* The types might not match because the caller might pass an rgctx */
8046 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8047 mono_llvm_replace_uses_of (callee, lmethod);
8048 mono_aot_mark_unused_llvm_plt_entry (ji);
8058 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
8059 g_assert_not_reached ();
8064 LLVMWriteBitcodeToFile (module->lmodule, filename);
8069 md_string (const char *s)
8071 return LLVMMDString (s, strlen (s));
8074 /* Debugging support */
8077 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8079 LLVMModuleRef lmodule = module->lmodule;
8080 LLVMValueRef args [16], cu_args [16], cu, ver;
8082 char *build_info, *s, *dir;
8085 * This can only be enabled when LLVM code is emitted into a separate object
8086 * file, since the AOT compiler also emits dwarf info,
8087 * and the abbrev indexes will not be correct since llvm has added its own
8090 if (!module->emit_dwarf)
8094 * Emit dwarf info in the form of LLVM metadata. There is some
8095 * out-of-date documentation at:
8096 * http://llvm.org/docs/SourceLevelDebugging.html
8097 * but most of this was gathered from the llvm and
8102 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8103 /* CU name/compilation dir */
8104 dir = g_path_get_dirname (filename);
8105 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8106 args [1] = LLVMMDString (dir, strlen (dir));
8107 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8110 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8112 build_info = mono_get_runtime_build_info ();
8113 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8114 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8115 g_free (build_info);
8117 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8119 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8120 /* Runtime version */
8121 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8123 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8124 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8126 if (module->subprogram_mds) {
8130 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8131 for (i = 0; i < module->subprogram_mds->len; ++i)
8132 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8133 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8135 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8138 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8139 /* Imported modules */
8140 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8142 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8143 /* DebugEmissionKind = FullDebug */
8144 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8145 cu = LLVMMDNode (cu_args, n_cuargs);
8146 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8148 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8149 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8150 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8151 ver = LLVMMDNode (args, 3);
8152 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8154 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8155 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8156 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8157 ver = LLVMMDNode (args, 3);
8158 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8162 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8164 MonoLLVMModule *module = ctx->module;
8165 MonoDebugMethodInfo *minfo = ctx->minfo;
8166 char *source_file, *dir, *filename;
8167 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8168 MonoSymSeqPoint *sym_seq_points;
8174 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8176 source_file = g_strdup ("<unknown>");
8177 dir = g_path_get_dirname (source_file);
8178 filename = g_path_get_basename (source_file);
8180 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8181 args [0] = md_string (filename);
8182 args [1] = md_string (dir);
8183 ctx_args [1] = LLVMMDNode (args, 2);
8184 ctx_md = LLVMMDNode (ctx_args, 2);
8186 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8187 type_args [1] = NULL;
8188 type_args [2] = NULL;
8189 type_args [3] = LLVMMDString ("", 0);
8190 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8191 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8192 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8193 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8194 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8195 type_args [9] = NULL;
8196 type_args [10] = NULL;
8197 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8198 type_args [12] = NULL;
8199 type_args [13] = NULL;
8200 type_args [14] = NULL;
8201 type_md = LLVMMDNode (type_args, 14);
8203 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8204 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8205 /* Source directory + file pair */
8206 args [0] = md_string (filename);
8207 args [1] = md_string (dir);
8208 md_args [1] = LLVMMDNode (args ,2);
8209 md_args [2] = ctx_md;
8210 md_args [3] = md_string (cfg->method->name);
8211 md_args [4] = md_string (name);
8212 md_args [5] = md_string (name);
8215 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8217 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8219 md_args [7] = type_md;
8221 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8223 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8225 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8226 /* Index into a virtual function */
8227 md_args [11] = NULL;
8228 md_args [12] = NULL;
8230 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8232 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8233 /* Pointer to LLVM function */
8234 md_args [15] = method;
8235 /* Function template parameter */
8236 md_args [16] = NULL;
8237 /* Function declaration descriptor */
8238 md_args [17] = NULL;
8239 /* List of function variables */
8240 md_args [18] = LLVMMDNode (args, 0);
8242 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8243 md = LLVMMDNode (md_args, 20);
8245 if (!module->subprogram_mds)
8246 module->subprogram_mds = g_ptr_array_new ();
8247 g_ptr_array_add (module->subprogram_mds, md);
8251 g_free (source_file);
8252 g_free (sym_seq_points);
8258 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8260 MonoCompile *cfg = ctx->cfg;
8262 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8263 MonoDebugSourceLocation *loc;
8264 LLVMValueRef loc_md, md_args [16];
8267 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8271 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8272 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8273 md_args [nmd_args ++] = ctx->dbg_md;
8274 md_args [nmd_args ++] = NULL;
8275 loc_md = LLVMMDNode (md_args, nmd_args);
8276 LLVMSetCurrentDebugLocation (builder, loc_md);
8277 mono_debug_symfile_free_location (loc);
8283 default_mono_llvm_unhandled_exception (void)
8285 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8286 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8288 mono_unhandled_exception (target);
8289 exit (mono_environment_exitcode_get ());
8294 - Emit LLVM IR from the mono IR using the LLVM C API.
8295 - The original arch specific code remains, so we can fall back to it if we run
8296 into something we can't handle.
8300 A partial list of issues:
8301 - Handling of opcodes which can throw exceptions.
8303 In the mono JIT, these are implemented using code like this:
8310 push throw_pos - method
8311 call <exception trampoline>
8313 The problematic part is push throw_pos - method, which cannot be represented
8314 in the LLVM IR, since it does not support label values.
8315 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8316 be implemented in JIT mode ?
8317 -> a possible but slower implementation would use the normal exception
8318 throwing code but it would need to control the placement of the throw code
8319 (it needs to be exactly after the compare+branch).
8320 -> perhaps add a PC offset intrinsics ?
8322 - efficient implementation of .ovf opcodes.
8324 These are currently implemented as:
8325 <ins which sets the condition codes>
8328 Some overflow opcodes are now supported by LLVM SVN.
8330 - exception handling, unwinding.
8331 - SSA is disabled for methods with exception handlers
8332 - How to obtain unwind info for LLVM compiled methods ?
8333 -> this is now solved by converting the unwind info generated by LLVM
8335 - LLVM uses the c++ exception handling framework, while we use our home grown
8336 code, and couldn't use the c++ one:
8337 - its not supported under VC++, other exotic platforms.
8338 - it might be impossible to support filter clauses with it.
8342 The trampolines need a predictable call sequence, since they need to disasm
8343 the calling code to obtain register numbers / offsets.
8345 LLVM currently generates this code in non-JIT mode:
8346 mov -0x98(%rax),%eax
8348 Here, the vtable pointer is lost.
8349 -> solution: use one vtable trampoline per class.
8351 - passing/receiving the IMT pointer/RGCTX.
8352 -> solution: pass them as normal arguments ?
8356 LLVM does not allow the specification of argument registers etc. This means
8357 that all calls are made according to the platform ABI.
8359 - passing/receiving vtypes.
8361 Vtypes passed/received in registers are handled by the front end by using
8362 a signature with scalar arguments, and loading the parts of the vtype into those
8365 Vtypes passed on the stack are handled using the 'byval' attribute.
8369 Supported though alloca, we need to emit the load/store code.
8373 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8374 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8375 This is made easier because the IR is already in SSA form.
8376 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8377 types are frequently used incorrectly.
8382 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8383 it with the file containing the methods emitted by the JIT and the AOT data
8387 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8388 * - each bblock should end with a branch
8389 * - setting the return value, making cfg->ret non-volatile
8390 * - avoid some transformations in the JIT which make it harder for us to generate
8392 * - use pointer types to help optimizations.