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)
1063 memset (&ji, 0, sizeof (ji));
1065 ji.data.target = target;
1067 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1068 mono_error_assert_ok (&error);
1076 * Emit code to convert the LLVM value V to DTYPE.
1079 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1081 LLVMTypeRef stype = LLVMTypeOf (v);
1083 if (stype != dtype) {
1084 gboolean ext = FALSE;
1087 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1089 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1091 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1095 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1097 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1098 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1101 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1102 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1103 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1104 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1105 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1106 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1107 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1108 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1110 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1111 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1112 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1113 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1114 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1115 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1117 if (mono_arch_is_soft_float ()) {
1118 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1119 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1120 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1121 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1124 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1128 LLVMDumpValue (LLVMConstNull (dtype));
1129 g_assert_not_reached ();
1137 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1139 return convert_full (ctx, v, dtype, FALSE);
1143 * emit_volatile_load:
1145 * If vreg is volatile, emit a load from its address.
1148 emit_volatile_load (EmitContext *ctx, int vreg)
1152 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1153 t = ctx->vreg_cli_types [vreg];
1154 if (t && !t->byref) {
1156 * Might have to zero extend since llvm doesn't have
1159 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1160 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1161 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1162 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1163 else if (t->type == MONO_TYPE_U8)
1164 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1171 * emit_volatile_store:
1173 * If VREG is volatile, emit a store from its value to its address.
1176 emit_volatile_store (EmitContext *ctx, int vreg)
1178 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1180 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1181 g_assert (ctx->addresses [vreg]);
1182 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1187 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1189 LLVMTypeRef ret_type;
1190 LLVMTypeRef *param_types = NULL;
1195 rtype = mini_get_underlying_type (sig->ret);
1196 ret_type = type_to_llvm_type (ctx, rtype);
1200 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1204 param_types [pindex ++] = ThisType ();
1205 for (i = 0; i < sig->param_count; ++i)
1206 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1208 if (!ctx_ok (ctx)) {
1209 g_free (param_types);
1213 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1214 g_free (param_types);
1220 * sig_to_llvm_sig_full:
1222 * Return the LLVM signature corresponding to the mono signature SIG using the
1223 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1226 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1228 LLVMTypeRef ret_type;
1229 LLVMTypeRef *param_types = NULL;
1231 int i, j, pindex, vret_arg_pindex = 0;
1232 gboolean vretaddr = FALSE;
1236 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1238 rtype = mini_get_underlying_type (sig->ret);
1239 ret_type = type_to_llvm_type (ctx, rtype);
1243 switch (cinfo->ret.storage) {
1244 case LLVMArgVtypeInReg:
1245 /* LLVM models this by returning an aggregate value */
1246 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1247 LLVMTypeRef members [2];
1249 members [0] = IntPtrType ();
1250 ret_type = LLVMStructType (members, 1, FALSE);
1251 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 ret_type = LLVMVoidType ();
1254 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1255 LLVMTypeRef members [2];
1257 members [0] = IntPtrType ();
1258 members [1] = IntPtrType ();
1259 ret_type = LLVMStructType (members, 2, FALSE);
1261 g_assert_not_reached ();
1264 case LLVMArgVtypeByVal:
1265 /* Vtype returned normally by val */
1267 case LLVMArgVtypeAsScalar: {
1268 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1269 /* LLVM models this by returning an int */
1270 if (size < SIZEOF_VOID_P) {
1271 g_assert (cinfo->ret.nslots == 1);
1272 ret_type = LLVMIntType (size * 8);
1274 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1275 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1279 case LLVMArgFpStruct: {
1280 /* Vtype returned as a fp struct */
1281 LLVMTypeRef members [16];
1283 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1284 for (i = 0; i < cinfo->ret.nslots; ++i)
1285 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1286 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1289 case LLVMArgVtypeByRef:
1290 /* Vtype returned using a hidden argument */
1291 ret_type = LLVMVoidType ();
1293 case LLVMArgVtypeRetAddr:
1294 case LLVMArgScalarRetAddr:
1295 case LLVMArgGsharedvtFixed:
1296 case LLVMArgGsharedvtFixedVtype:
1297 case LLVMArgGsharedvtVariable:
1299 ret_type = LLVMVoidType ();
1305 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1307 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1309 * Has to be the first argument because of the sret argument attribute
1310 * FIXME: This might conflict with passing 'this' as the first argument, but
1311 * this is only used on arm64 which has a dedicated struct return register.
1313 cinfo->vret_arg_pindex = pindex;
1314 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1315 if (!ctx_ok (ctx)) {
1316 g_free (param_types);
1319 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1322 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1323 cinfo->rgctx_arg_pindex = pindex;
1324 param_types [pindex] = ctx->module->ptr_type;
1327 if (cinfo->imt_arg) {
1328 cinfo->imt_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1333 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1334 vret_arg_pindex = pindex;
1335 if (cinfo->vret_arg_index == 1) {
1336 /* Add the slots consumed by the first argument */
1337 LLVMArgInfo *ainfo = &cinfo->args [0];
1338 switch (ainfo->storage) {
1339 case LLVMArgVtypeInReg:
1340 for (j = 0; j < 2; ++j) {
1341 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1350 cinfo->vret_arg_pindex = vret_arg_pindex;
1353 if (vretaddr && vret_arg_pindex == pindex)
1354 param_types [pindex ++] = IntPtrType ();
1356 cinfo->this_arg_pindex = pindex;
1357 param_types [pindex ++] = ThisType ();
1358 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1360 if (vretaddr && vret_arg_pindex == pindex)
1361 param_types [pindex ++] = IntPtrType ();
1362 for (i = 0; i < sig->param_count; ++i) {
1363 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 ainfo->pindex = pindex;
1369 switch (ainfo->storage) {
1370 case LLVMArgVtypeInReg:
1371 for (j = 0; j < 2; ++j) {
1372 switch (ainfo->pair_storage [j]) {
1374 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1379 g_assert_not_reached ();
1383 case LLVMArgVtypeByVal:
1384 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1387 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1390 case LLVMArgAsIArgs:
1391 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1394 case LLVMArgVtypeByRef:
1395 case LLVMArgScalarByRef:
1396 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1399 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1402 case LLVMArgAsFpArgs: {
1405 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1406 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1407 param_types [pindex ++] = LLVMDoubleType ();
1408 for (j = 0; j < ainfo->nslots; ++j)
1409 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1412 case LLVMArgVtypeAsScalar:
1413 g_assert_not_reached ();
1415 case LLVMArgGsharedvtFixed:
1416 case LLVMArgGsharedvtFixedVtype:
1417 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1419 case LLVMArgGsharedvtVariable:
1420 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1423 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 if (!ctx_ok (ctx)) {
1428 g_free (param_types);
1431 if (vretaddr && vret_arg_pindex == pindex)
1432 param_types [pindex ++] = IntPtrType ();
1433 if (ctx->llvm_only && cinfo->rgctx_arg) {
1434 /* Pass the rgctx as the last argument */
1435 cinfo->rgctx_arg_pindex = pindex;
1436 param_types [pindex] = ctx->module->ptr_type;
1440 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1441 g_free (param_types);
1447 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1449 return sig_to_llvm_sig_full (ctx, sig, NULL);
1453 * LLVMFunctionType1:
1455 * Create an LLVM function type from the arguments.
1457 static G_GNUC_UNUSED LLVMTypeRef
1458 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1461 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1465 * LLVMFunctionType1:
1467 * Create an LLVM function type from the arguments.
1469 static G_GNUC_UNUSED LLVMTypeRef
1470 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1471 LLVMTypeRef ParamType1,
1474 LLVMTypeRef param_types [1];
1476 param_types [0] = ParamType1;
1478 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1482 * LLVMFunctionType2:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1492 LLVMTypeRef param_types [2];
1494 param_types [0] = ParamType1;
1495 param_types [1] = ParamType2;
1497 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1501 * LLVMFunctionType3:
1503 * Create an LLVM function type from the arguments.
1505 static G_GNUC_UNUSED LLVMTypeRef
1506 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1507 LLVMTypeRef ParamType1,
1508 LLVMTypeRef ParamType2,
1509 LLVMTypeRef ParamType3,
1512 LLVMTypeRef param_types [3];
1514 param_types [0] = ParamType1;
1515 param_types [1] = ParamType2;
1516 param_types [2] = ParamType3;
1518 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1521 static G_GNUC_UNUSED LLVMTypeRef
1522 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1523 LLVMTypeRef ParamType1,
1524 LLVMTypeRef ParamType2,
1525 LLVMTypeRef ParamType3,
1526 LLVMTypeRef ParamType4,
1527 LLVMTypeRef ParamType5,
1530 LLVMTypeRef param_types [5];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1534 param_types [2] = ParamType3;
1535 param_types [3] = ParamType4;
1536 param_types [4] = ParamType5;
1538 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1544 * Create an LLVM builder and remember it so it can be freed later.
1546 static LLVMBuilderRef
1547 create_builder (EmitContext *ctx)
1549 LLVMBuilderRef builder = LLVMCreateBuilder ();
1551 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1557 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1562 case MONO_PATCH_INFO_INTERNAL_METHOD:
1563 name = g_strdup_printf ("jit_icall_%s", data);
1565 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1566 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1567 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1571 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1579 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1583 LLVMValueRef indexes [2];
1585 LLVMValueRef got_entry_addr, load;
1586 LLVMBuilderRef builder = ctx->builder;
1591 ji = g_new0 (MonoJumpInfo, 1);
1593 ji->data.target = data;
1595 ji = mono_aot_patch_info_dup (ji);
1597 ji->next = cfg->patch_info;
1598 cfg->patch_info = ji;
1600 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1601 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1603 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1604 * explicitly initialize it.
1606 if (!mono_aot_is_shared_got_offset (got_offset)) {
1607 //mono_print_ji (ji);
1609 ctx->has_got_access = TRUE;
1612 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1613 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1614 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1616 name = get_aotconst_name (type, data, got_offset);
1618 load = LLVMBuildLoad (builder, got_entry_addr, "");
1619 load = convert (ctx, load, llvm_type);
1620 LLVMSetValueName (load, name ? name : "");
1622 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1625 //set_invariant_load_flag (load);
1631 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1633 return get_aotconst_typed (ctx, type, data, NULL);
1637 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1639 LLVMValueRef callee;
1641 if (ctx->llvm_only) {
1642 callee_name = mono_aot_get_direct_call_symbol (type, data);
1644 /* Directly callable */
1646 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1648 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1650 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1652 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1654 /* LLVMTypeRef's are uniqued */
1655 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1656 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1658 g_free (callee_name);
1664 * Calls are made through the GOT.
1666 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1668 MonoJumpInfo *ji = NULL;
1670 callee_name = mono_aot_get_plt_symbol (type, data);
1674 if (ctx->cfg->compile_aot)
1675 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1676 mono_add_patch_info (ctx->cfg, 0, type, data);
1679 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1681 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1683 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1685 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1688 if (ctx->cfg->compile_aot) {
1689 ji = g_new0 (MonoJumpInfo, 1);
1691 ji->data.target = data;
1693 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1701 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1703 MonoMethodHeader *header = cfg->header;
1704 MonoExceptionClause *clause;
1708 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1709 return (bb->region >> 8) - 1;
1712 for (i = 0; i < header->num_clauses; ++i) {
1713 clause = &header->clauses [i];
1715 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1722 static MonoExceptionClause *
1723 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1725 // Since they're sorted by nesting we just need
1726 // the first one that the bb is a member of
1727 MonoExceptionClause *last = NULL;
1729 for (int i = 0; i < cfg->header->num_clauses; i++) {
1730 MonoExceptionClause *curr = &cfg->header->clauses [i];
1732 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1735 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1736 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1750 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1752 LLVMValueRef md_arg;
1755 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1756 md_arg = LLVMMDString ("mono", 4);
1757 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1761 set_invariant_load_flag (LLVMValueRef v)
1763 LLVMValueRef md_arg;
1765 const char *flag_name;
1767 // FIXME: Cache this
1768 flag_name = "invariant.load";
1769 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1770 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1771 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1777 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1781 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1783 MonoCompile *cfg = ctx->cfg;
1784 LLVMValueRef lcall = NULL;
1785 LLVMBuilderRef builder = *builder_ref;
1786 MonoExceptionClause *clause;
1788 if (ctx->llvm_only) {
1789 clause = get_most_deep_clause (cfg, ctx, bb);
1792 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1795 * Have to use an invoke instead of a call, branching to the
1796 * handler bblock of the clause containing this bblock.
1798 intptr_t key = CLAUSE_END(clause);
1800 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1802 // FIXME: Find the one that has the lowest end bound for the right start address
1803 // FIXME: Finally + nesting
1806 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1809 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1811 builder = ctx->builder = create_builder (ctx);
1812 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1814 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1818 int clause_index = get_handler_clause (cfg, bb);
1820 if (clause_index != -1) {
1821 MonoMethodHeader *header = cfg->header;
1822 MonoExceptionClause *ec = &header->clauses [clause_index];
1823 MonoBasicBlock *tblock;
1824 LLVMBasicBlockRef ex_bb, noex_bb;
1827 * Have to use an invoke instead of a call, branching to the
1828 * handler bblock of the clause containing this bblock.
1831 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1833 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1836 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1838 ex_bb = get_bb (ctx, tblock);
1840 noex_bb = gen_bb (ctx, "NOEX_BB");
1843 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1845 builder = ctx->builder = create_builder (ctx);
1846 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1848 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1853 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1854 ctx->builder = builder;
1858 *builder_ref = ctx->builder;
1864 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1866 const char *intrins_name;
1867 LLVMValueRef args [16], res;
1868 LLVMTypeRef addr_type;
1870 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1871 LLVMAtomicOrdering ordering;
1874 case LLVM_BARRIER_NONE:
1875 ordering = LLVMAtomicOrderingNotAtomic;
1877 case LLVM_BARRIER_ACQ:
1878 ordering = LLVMAtomicOrderingAcquire;
1880 case LLVM_BARRIER_SEQ:
1881 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1884 g_assert_not_reached ();
1889 * We handle loads which can fault by calling a mono specific intrinsic
1890 * using an invoke, so they are handled properly inside try blocks.
1891 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1892 * are marked with IntrReadArgMem.
1896 intrins_name = "llvm.mono.load.i8.p0i8";
1899 intrins_name = "llvm.mono.load.i16.p0i16";
1902 intrins_name = "llvm.mono.load.i32.p0i32";
1905 intrins_name = "llvm.mono.load.i64.p0i64";
1908 g_assert_not_reached ();
1911 addr_type = LLVMTypeOf (addr);
1912 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1913 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1916 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1917 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1918 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1919 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1921 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1922 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1923 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1924 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1931 * We emit volatile loads for loads which can fault, because otherwise
1932 * LLVM will generate invalid code when encountering a load from a
1935 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1937 /* Mark it with a custom metadata */
1940 set_metadata_flag (res, "mono.faulting.load");
1948 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1950 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1954 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1956 const char *intrins_name;
1957 LLVMValueRef args [16];
1959 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1960 LLVMAtomicOrdering ordering;
1963 case LLVM_BARRIER_NONE:
1964 ordering = LLVMAtomicOrderingNotAtomic;
1966 case LLVM_BARRIER_REL:
1967 ordering = LLVMAtomicOrderingRelease;
1969 case LLVM_BARRIER_SEQ:
1970 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1973 g_assert_not_reached ();
1979 intrins_name = "llvm.mono.store.i8.p0i8";
1982 intrins_name = "llvm.mono.store.i16.p0i16";
1985 intrins_name = "llvm.mono.store.i32.p0i32";
1988 intrins_name = "llvm.mono.store.i64.p0i64";
1991 g_assert_not_reached ();
1994 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1995 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1996 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2001 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2002 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2003 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2004 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2006 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2011 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2013 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2017 * emit_cond_system_exception:
2019 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2020 * Might set the ctx exception.
2023 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2025 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2026 LLVMBuilderRef builder;
2027 MonoClass *exc_class;
2028 LLVMValueRef args [2];
2029 LLVMValueRef callee;
2031 ex_bb = gen_bb (ctx, "EX_BB");
2033 ex2_bb = gen_bb (ctx, "EX2_BB");
2034 noex_bb = gen_bb (ctx, "NOEX_BB");
2036 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2038 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2039 g_assert (exc_class);
2041 /* Emit exception throwing code */
2042 ctx->builder = builder = create_builder (ctx);
2043 LLVMPositionBuilderAtEnd (builder, ex_bb);
2045 if (ctx->cfg->llvm_only) {
2046 static LLVMTypeRef sig;
2049 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2050 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2052 LLVMBuildBr (builder, ex2_bb);
2054 ctx->builder = builder = create_builder (ctx);
2055 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2057 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2058 emit_call (ctx, bb, &builder, callee, args, 1);
2059 LLVMBuildUnreachable (builder);
2061 ctx->builder = builder = create_builder (ctx);
2062 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2064 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2070 callee = ctx->module->throw_corlib_exception;
2073 const char *icall_name;
2075 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2076 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2078 if (ctx->cfg->compile_aot) {
2079 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2081 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2084 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2085 * - On x86, LLVM generated code doesn't push the arguments
2086 * - The trampoline takes the throw address as an arguments, not a pc offset.
2088 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2090 mono_memory_barrier ();
2091 ctx->module->throw_corlib_exception = callee;
2095 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2096 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2098 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2101 * The LLVM mono branch contains changes so a block address can be passed as an
2102 * argument to a call.
2104 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2105 emit_call (ctx, bb, &builder, callee, args, 2);
2107 LLVMBuildUnreachable (builder);
2109 ctx->builder = builder = create_builder (ctx);
2110 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2112 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2119 * emit_args_to_vtype:
2121 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2124 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2126 int j, size, nslots;
2128 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2130 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2131 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2134 if (ainfo->storage == LLVMArgAsFpArgs)
2135 nslots = ainfo->nslots;
2139 for (j = 0; j < nslots; ++j) {
2140 LLVMValueRef index [2], addr, daddr;
2141 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2142 LLVMTypeRef part_type;
2144 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2147 if (ainfo->pair_storage [j] == LLVMArgNone)
2150 switch (ainfo->pair_storage [j]) {
2151 case LLVMArgInIReg: {
2152 part_type = LLVMIntType (part_size * 8);
2153 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2154 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2155 addr = LLVMBuildGEP (builder, address, index, 1, "");
2157 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2158 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2159 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2161 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2164 case LLVMArgInFPReg: {
2165 LLVMTypeRef arg_type;
2167 if (ainfo->esize == 8)
2168 arg_type = LLVMDoubleType ();
2170 arg_type = LLVMFloatType ();
2172 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2173 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2174 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2175 LLVMBuildStore (builder, args [j], addr);
2181 g_assert_not_reached ();
2184 size -= sizeof (gpointer);
2189 * emit_vtype_to_args:
2191 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2192 * into ARGS, and the number of arguments into NARGS.
2195 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2198 int j, size, nslots;
2199 LLVMTypeRef arg_type;
2201 size = get_vtype_size (t);
2203 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2204 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2206 if (ainfo->storage == LLVMArgAsFpArgs)
2207 nslots = ainfo->nslots;
2210 for (j = 0; j < nslots; ++j) {
2211 LLVMValueRef index [2], addr, daddr;
2212 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2214 if (ainfo->pair_storage [j] == LLVMArgNone)
2217 switch (ainfo->pair_storage [j]) {
2219 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2220 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2221 addr = LLVMBuildGEP (builder, address, index, 1, "");
2223 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2224 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2225 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2227 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2229 case LLVMArgInFPReg:
2230 if (ainfo->esize == 8)
2231 arg_type = LLVMDoubleType ();
2233 arg_type = LLVMFloatType ();
2234 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2235 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2236 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2237 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2242 g_assert_not_reached ();
2244 size -= sizeof (gpointer);
2251 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2254 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2255 * get executed every time control reaches them.
2257 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2259 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2260 return ctx->last_alloca;
2264 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2266 return build_alloca_llvm_type_name (ctx, t, align, "");
2270 build_alloca (EmitContext *ctx, MonoType *t)
2272 MonoClass *k = mono_class_from_mono_type (t);
2275 g_assert (!mini_is_gsharedvt_variable_type (t));
2277 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2280 align = mono_class_min_align (k);
2282 /* Sometimes align is not a power of 2 */
2283 while (mono_is_power_of_two (align) == -1)
2286 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2290 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2294 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2296 MonoCompile *cfg = ctx->cfg;
2297 LLVMBuilderRef builder = ctx->builder;
2298 LLVMValueRef offset, offset_var;
2299 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2300 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2304 g_assert (info_var);
2305 g_assert (locals_var);
2307 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2309 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2310 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2312 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2313 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2315 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2319 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2322 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2325 module->used = g_ptr_array_sized_new (16);
2326 g_ptr_array_add (module->used, global);
2330 emit_llvm_used (MonoLLVMModule *module)
2332 LLVMModuleRef lmodule = module->lmodule;
2333 LLVMTypeRef used_type;
2334 LLVMValueRef used, *used_elem;
2340 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2341 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2342 used_elem = g_new0 (LLVMValueRef, module->used->len);
2343 for (i = 0; i < module->used->len; ++i)
2344 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2345 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2346 LLVMSetLinkage (used, LLVMAppendingLinkage);
2347 LLVMSetSection (used, "llvm.metadata");
2353 * Emit a function mapping method indexes to their code
2356 emit_get_method (MonoLLVMModule *module)
2358 LLVMModuleRef lmodule = module->lmodule;
2359 LLVMValueRef func, switch_ins, m;
2360 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2361 LLVMBasicBlockRef *bbs;
2363 LLVMBuilderRef builder;
2368 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2369 * but generating code seems safer.
2371 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2372 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2373 LLVMSetLinkage (func, LLVMExternalLinkage);
2374 LLVMSetVisibility (func, LLVMHiddenVisibility);
2375 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2376 module->get_method = func;
2378 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2381 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2382 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2383 * then we will have to find another solution.
2386 name = g_strdup_printf ("BB_CODE_START");
2387 code_start_bb = LLVMAppendBasicBlock (func, name);
2389 builder = LLVMCreateBuilder ();
2390 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2391 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2393 name = g_strdup_printf ("BB_CODE_END");
2394 code_end_bb = LLVMAppendBasicBlock (func, name);
2396 builder = LLVMCreateBuilder ();
2397 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2398 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2400 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2401 for (i = 0; i < module->max_method_idx + 1; ++i) {
2402 name = g_strdup_printf ("BB_%d", i);
2403 bb = LLVMAppendBasicBlock (func, name);
2407 builder = LLVMCreateBuilder ();
2408 LLVMPositionBuilderAtEnd (builder, bb);
2410 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2412 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2414 LLVMBuildRet (builder, LLVMConstNull (rtype));
2417 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2418 builder = LLVMCreateBuilder ();
2419 LLVMPositionBuilderAtEnd (builder, fail_bb);
2420 LLVMBuildRet (builder, LLVMConstNull (rtype));
2422 builder = LLVMCreateBuilder ();
2423 LLVMPositionBuilderAtEnd (builder, entry_bb);
2425 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2426 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2427 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2428 for (i = 0; i < module->max_method_idx + 1; ++i) {
2429 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2432 mark_as_used (module, func);
2436 * emit_get_unbox_tramp:
2438 * Emit a function mapping method indexes to their unbox trampoline
2441 emit_get_unbox_tramp (MonoLLVMModule *module)
2443 LLVMModuleRef lmodule = module->lmodule;
2444 LLVMValueRef func, switch_ins, m;
2445 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2446 LLVMBasicBlockRef *bbs;
2448 LLVMBuilderRef builder;
2452 /* Similar to emit_get_method () */
2454 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2455 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2456 LLVMSetLinkage (func, LLVMExternalLinkage);
2457 LLVMSetVisibility (func, LLVMHiddenVisibility);
2458 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2459 module->get_unbox_tramp = func;
2461 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2463 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2464 for (i = 0; i < module->max_method_idx + 1; ++i) {
2465 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2469 name = g_strdup_printf ("BB_%d", i);
2470 bb = LLVMAppendBasicBlock (func, name);
2474 builder = LLVMCreateBuilder ();
2475 LLVMPositionBuilderAtEnd (builder, bb);
2477 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2480 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2481 builder = LLVMCreateBuilder ();
2482 LLVMPositionBuilderAtEnd (builder, fail_bb);
2483 LLVMBuildRet (builder, LLVMConstNull (rtype));
2485 builder = LLVMCreateBuilder ();
2486 LLVMPositionBuilderAtEnd (builder, entry_bb);
2488 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2489 for (i = 0; i < module->max_method_idx + 1; ++i) {
2490 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2494 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2497 mark_as_used (module, func);
2500 /* Add a function to mark the beginning of LLVM code */
2502 emit_llvm_code_start (MonoLLVMModule *module)
2504 LLVMModuleRef lmodule = module->lmodule;
2506 LLVMBasicBlockRef entry_bb;
2507 LLVMBuilderRef builder;
2509 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2510 LLVMSetLinkage (func, LLVMInternalLinkage);
2511 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2512 module->code_start = func;
2513 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2514 builder = LLVMCreateBuilder ();
2515 LLVMPositionBuilderAtEnd (builder, entry_bb);
2516 LLVMBuildRetVoid (builder);
2520 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2522 LLVMModuleRef lmodule = module->lmodule;
2523 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2524 LLVMBasicBlockRef entry_bb;
2525 LLVMBuilderRef builder;
2532 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2533 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2538 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2539 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2542 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2543 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2546 g_assert_not_reached ();
2548 LLVMSetLinkage (func, LLVMInternalLinkage);
2549 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2550 mono_llvm_set_preserveall_cc (func);
2551 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2552 builder = LLVMCreateBuilder ();
2553 LLVMPositionBuilderAtEnd (builder, entry_bb);
2556 ji = g_new0 (MonoJumpInfo, 1);
2557 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2558 ji = mono_aot_patch_info_dup (ji);
2559 got_offset = mono_aot_get_got_offset (ji);
2560 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2561 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2562 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2563 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2564 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2565 args [1] = LLVMGetParam (func, 0);
2567 args [2] = LLVMGetParam (func, 1);
2569 ji = g_new0 (MonoJumpInfo, 1);
2570 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2571 ji->data.name = icall_name;
2572 ji = mono_aot_patch_info_dup (ji);
2573 got_offset = mono_aot_get_got_offset (ji);
2574 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2575 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2576 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2577 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2578 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2579 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2580 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2582 // Set the inited flag
2583 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2584 indexes [1] = LLVMGetParam (func, 0);
2585 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2587 LLVMBuildRetVoid (builder);
2589 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2594 * Emit wrappers around the C icalls used to initialize llvm methods, to
2595 * make the calling code smaller and to enable usage of the llvm
2596 * PreserveAll calling convention.
2599 emit_init_icall_wrappers (MonoLLVMModule *module)
2601 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2602 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2603 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2604 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2608 emit_llvm_code_end (MonoLLVMModule *module)
2610 LLVMModuleRef lmodule = module->lmodule;
2612 LLVMBasicBlockRef entry_bb;
2613 LLVMBuilderRef builder;
2615 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2616 LLVMSetLinkage (func, LLVMInternalLinkage);
2617 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2618 module->code_end = func;
2619 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2620 builder = LLVMCreateBuilder ();
2621 LLVMPositionBuilderAtEnd (builder, entry_bb);
2622 LLVMBuildRetVoid (builder);
2626 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2628 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2631 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2632 need_div_check = TRUE;
2634 if (!need_div_check)
2637 switch (ins->opcode) {
2650 case OP_IDIV_UN_IMM:
2651 case OP_LDIV_UN_IMM:
2652 case OP_IREM_UN_IMM:
2653 case OP_LREM_UN_IMM: {
2655 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2656 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2658 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2659 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2662 builder = ctx->builder;
2664 /* b == -1 && a == 0x80000000 */
2666 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2667 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2668 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2670 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2671 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2674 builder = ctx->builder;
2686 * Emit code to initialize the GOT slots used by the method.
2689 emit_init_method (EmitContext *ctx)
2691 LLVMValueRef indexes [16], args [16], callee;
2692 LLVMValueRef inited_var, cmp, call;
2693 LLVMBasicBlockRef inited_bb, notinited_bb;
2694 LLVMBuilderRef builder = ctx->builder;
2695 MonoCompile *cfg = ctx->cfg;
2697 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2699 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2700 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2701 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2703 args [0] = inited_var;
2704 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2705 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2707 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2709 inited_bb = ctx->inited_bb;
2710 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2712 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2714 builder = ctx->builder = create_builder (ctx);
2715 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2718 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2719 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2720 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2721 callee = ctx->module->init_method_gshared_mrgctx;
2722 call = LLVMBuildCall (builder, callee, args, 2, "");
2723 } else if (ctx->rgctx_arg) {
2724 /* A vtable is passed as the rgctx argument */
2725 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2726 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2727 callee = ctx->module->init_method_gshared_vtable;
2728 call = LLVMBuildCall (builder, callee, args, 2, "");
2729 } else if (cfg->gshared) {
2730 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2731 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2732 callee = ctx->module->init_method_gshared_this;
2733 call = LLVMBuildCall (builder, callee, args, 2, "");
2735 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2736 callee = ctx->module->init_method;
2737 call = LLVMBuildCall (builder, callee, args, 1, "");
2741 * This enables llvm to keep arguments in their original registers/
2742 * scratch registers, since the call will not clobber them.
2744 mono_llvm_set_call_preserveall_cc (call);
2746 LLVMBuildBr (builder, inited_bb);
2747 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2749 builder = ctx->builder = create_builder (ctx);
2750 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2754 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2757 * Emit unbox trampoline using a tail call
2759 LLVMValueRef tramp, call, *args;
2760 LLVMBuilderRef builder;
2761 LLVMBasicBlockRef lbb;
2762 LLVMCallInfo *linfo;
2766 tramp_name = g_strdup_printf ("ut_%s", method_name);
2767 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2768 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2769 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2770 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2772 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2773 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2774 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2775 if (ctx->cfg->vret_addr) {
2776 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2777 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2778 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2779 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2783 lbb = LLVMAppendBasicBlock (tramp, "");
2784 builder = LLVMCreateBuilder ();
2785 LLVMPositionBuilderAtEnd (builder, lbb);
2787 nargs = LLVMCountParamTypes (method_type);
2788 args = g_new0 (LLVMValueRef, nargs);
2789 for (i = 0; i < nargs; ++i) {
2790 args [i] = LLVMGetParam (tramp, i);
2791 if (i == ctx->this_arg_pindex) {
2792 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2794 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2795 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2796 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2799 call = LLVMBuildCall (builder, method, args, nargs, "");
2800 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2801 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2802 if (linfo->ret.storage == LLVMArgVtypeByRef)
2803 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2805 // FIXME: This causes assertions in clang
2806 //mono_llvm_set_must_tail (call);
2807 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2808 LLVMBuildRetVoid (builder);
2810 LLVMBuildRet (builder, call);
2812 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2818 * Emit code to load/convert arguments.
2821 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2824 MonoCompile *cfg = ctx->cfg;
2825 MonoMethodSignature *sig = ctx->sig;
2826 LLVMCallInfo *linfo = ctx->linfo;
2830 LLVMBuilderRef old_builder = ctx->builder;
2831 ctx->builder = builder;
2833 ctx->alloca_builder = create_builder (ctx);
2836 * Handle indirect/volatile variables by allocating memory for them
2837 * using 'alloca', and storing their address in a temporary.
2839 for (i = 0; i < cfg->num_varinfo; ++i) {
2840 MonoInst *var = cfg->varinfo [i];
2843 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2844 } 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))) {
2845 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2848 /* Could be already created by an OP_VPHI */
2849 if (!ctx->addresses [var->dreg]) {
2850 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2851 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2853 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2857 names = g_new (char *, sig->param_count);
2858 mono_method_get_param_names (cfg->method, (const char **) names);
2860 for (i = 0; i < sig->param_count; ++i) {
2861 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2862 int reg = cfg->args [i + sig->hasthis]->dreg;
2865 pindex = ainfo->pindex;
2867 switch (ainfo->storage) {
2868 case LLVMArgVtypeInReg:
2869 case LLVMArgAsFpArgs: {
2870 LLVMValueRef args [8];
2873 pindex += ainfo->ndummy_fpargs;
2875 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2876 memset (args, 0, sizeof (args));
2877 if (ainfo->storage == LLVMArgVtypeInReg) {
2878 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2879 if (ainfo->pair_storage [1] != LLVMArgNone)
2880 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2882 g_assert (ainfo->nslots <= 8);
2883 for (j = 0; j < ainfo->nslots; ++j)
2884 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2886 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2888 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2890 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2891 /* Treat these as normal values */
2892 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2896 case LLVMArgVtypeByVal: {
2897 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2899 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2900 /* Treat these as normal values */
2901 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2905 case LLVMArgVtypeByRef: {
2906 /* The argument is passed by ref */
2907 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2910 case LLVMArgScalarByRef: {
2912 name = g_strdup_printf ("arg_%s", names [i]);
2914 name = g_strdup_printf ("arg_%d", i);
2915 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2919 case LLVMArgAsIArgs: {
2920 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2923 /* The argument is received as an array of ints, store it into the real argument */
2924 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2926 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2927 if (size < SIZEOF_VOID_P) {
2928 /* The upper bits of the registers might not be valid */
2929 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2930 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2931 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2933 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2937 case LLVMArgVtypeAsScalar:
2938 g_assert_not_reached ();
2940 case LLVMArgGsharedvtFixed: {
2941 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2942 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2945 name = g_strdup_printf ("arg_%s", names [i]);
2947 name = g_strdup_printf ("arg_%d", i);
2949 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2952 case LLVMArgGsharedvtFixedVtype: {
2953 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2956 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2958 name = g_strdup_printf ("vtype_arg_%d", i);
2960 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2961 g_assert (ctx->addresses [reg]);
2962 LLVMSetValueName (ctx->addresses [reg], name);
2963 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2966 case LLVMArgGsharedvtVariable:
2967 /* The IR treats these as variables with addresses */
2968 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2971 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));
2978 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2980 emit_volatile_store (ctx, cfg->args [0]->dreg);
2981 for (i = 0; i < sig->param_count; ++i)
2982 if (!mini_type_is_vtype (sig->params [i]))
2983 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2985 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2986 LLVMValueRef this_alloc;
2989 * The exception handling code needs the location where the this argument was
2990 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2991 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2992 * location into the LSDA.
2994 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2995 /* This volatile store will keep the alloca alive */
2996 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2998 set_metadata_flag (this_alloc, "mono.this");
3001 if (cfg->rgctx_var) {
3002 LLVMValueRef rgctx_alloc, store;
3005 * We handle the rgctx arg similarly to the this pointer.
3007 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3008 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3009 /* This volatile store will keep the alloca alive */
3010 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3012 set_metadata_flag (rgctx_alloc, "mono.this");
3015 /* Initialize the method if needed */
3016 if (cfg->compile_aot && ctx->llvm_only) {
3017 /* Emit a location for the initialization code */
3018 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3019 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3021 LLVMBuildBr (ctx->builder, ctx->init_bb);
3022 builder = ctx->builder = create_builder (ctx);
3023 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3024 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3027 /* Compute nesting between clauses */
3028 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3029 for (i = 0; i < cfg->header->num_clauses; ++i) {
3030 for (j = 0; j < cfg->header->num_clauses; ++j) {
3031 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3032 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3034 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3035 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3040 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3041 * it needs to continue normally, or return back to the exception handling system.
3043 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3047 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3050 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3051 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3052 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3054 if (bb->in_scount == 0) {
3057 sprintf (name, "finally_ind_bb%d", bb->block_num);
3058 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3059 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3061 ctx->bblocks [bb->block_num].finally_ind = val;
3063 /* Create a variable to hold the exception var */
3065 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3069 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3070 * LLVM bblock containing a landing pad causes problems for the
3071 * LLVM optimizer passes.
3073 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3074 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3076 ctx->builder = old_builder;
3080 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3082 MonoCompile *cfg = ctx->cfg;
3083 LLVMModuleRef lmodule = ctx->lmodule;
3084 LLVMValueRef *values = ctx->values;
3085 LLVMValueRef *addresses = ctx->addresses;
3086 MonoCallInst *call = (MonoCallInst*)ins;
3087 MonoMethodSignature *sig = call->signature;
3088 LLVMValueRef callee = NULL, lcall;
3090 LLVMCallInfo *cinfo;
3094 LLVMTypeRef llvm_sig;
3096 gboolean is_virtual, calli, preserveall;
3097 LLVMBuilderRef builder = *builder_ref;
3099 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3100 set_failure (ctx, "non-default callconv");
3104 cinfo = call->cinfo;
3106 if (call->rgctx_arg_reg)
3107 cinfo->rgctx_arg = TRUE;
3108 if (call->imt_arg_reg)
3109 cinfo->imt_arg = TRUE;
3111 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);
3113 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3117 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);
3118 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);
3120 preserveall = FALSE;
3122 /* FIXME: Avoid creating duplicate methods */
3124 if (ins->flags & MONO_INST_HAS_METHOD) {
3128 if (cfg->compile_aot) {
3129 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3131 set_failure (ctx, "can't encode patch");
3134 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3136 * Collect instructions representing the callee into a hash so they can be replaced
3137 * by the llvm method for the callee if the callee turns out to be direct
3138 * callable. Currently this only requires it to not fail llvm compilation.
3140 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3141 l = g_slist_prepend (l, callee);
3142 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3145 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3148 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3150 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3154 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3155 /* LLVM miscompiles async methods */
3156 set_failure (ctx, "#13734");
3161 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3167 memset (&ji, 0, sizeof (ji));
3168 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3169 ji.data.target = info->name;
3171 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3173 if (cfg->compile_aot) {
3174 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3176 set_failure (ctx, "can't encode patch");
3180 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3181 target = (gpointer)mono_icall_get_wrapper (info);
3182 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3185 if (cfg->compile_aot) {
3187 if (cfg->abs_patches) {
3188 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3190 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3192 set_failure (ctx, "can't encode patch");
3198 set_failure (ctx, "aot");
3202 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3204 if (cfg->abs_patches) {
3205 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3210 * FIXME: Some trampolines might have
3211 * their own calling convention on some platforms.
3213 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3214 mono_error_assert_ok (&error);
3215 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3219 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3225 int size = sizeof (gpointer);
3228 g_assert (ins->inst_offset % size == 0);
3229 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3231 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3233 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3235 if (ins->flags & MONO_INST_HAS_METHOD) {
3240 * Collect and convert arguments
3242 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3243 len = sizeof (LLVMValueRef) * nargs;
3244 args = (LLVMValueRef*)alloca (len);
3245 memset (args, 0, len);
3246 l = call->out_ireg_args;
3248 if (call->rgctx_arg_reg) {
3249 g_assert (values [call->rgctx_arg_reg]);
3250 g_assert (cinfo->rgctx_arg_pindex < nargs);
3252 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3253 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3254 * it using a volatile load.
3257 if (!ctx->imt_rgctx_loc)
3258 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3259 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3260 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3262 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3265 if (call->imt_arg_reg) {
3266 g_assert (!ctx->llvm_only);
3267 g_assert (values [call->imt_arg_reg]);
3268 g_assert (cinfo->imt_arg_pindex < nargs);
3270 if (!ctx->imt_rgctx_loc)
3271 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3272 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3273 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3275 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3278 switch (cinfo->ret.storage) {
3279 case LLVMArgGsharedvtVariable: {
3280 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3282 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3283 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3285 g_assert (addresses [call->inst.dreg]);
3286 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3292 if (!addresses [call->inst.dreg])
3293 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3294 g_assert (cinfo->vret_arg_pindex < nargs);
3295 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3296 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3298 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3304 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3305 * use the real callee for argument type conversion.
3307 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3308 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3309 LLVMGetParamTypes (callee_type, param_types);
3311 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3314 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3316 pindex = ainfo->pindex;
3318 regpair = (guint32)(gssize)(l->data);
3319 reg = regpair & 0xffffff;
3320 args [pindex] = values [reg];
3321 switch (ainfo->storage) {
3322 case LLVMArgVtypeInReg:
3323 case LLVMArgAsFpArgs: {
3327 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3328 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3329 pindex += ainfo->ndummy_fpargs;
3331 g_assert (addresses [reg]);
3332 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3336 // FIXME: Get rid of the VMOVE
3339 case LLVMArgVtypeByVal:
3340 g_assert (addresses [reg]);
3341 args [pindex] = addresses [reg];
3343 case LLVMArgVtypeByRef:
3344 case LLVMArgScalarByRef: {
3345 g_assert (addresses [reg]);
3346 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3349 case LLVMArgAsIArgs:
3350 g_assert (addresses [reg]);
3351 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3353 case LLVMArgVtypeAsScalar:
3354 g_assert_not_reached ();
3356 case LLVMArgGsharedvtFixed:
3357 case LLVMArgGsharedvtFixedVtype:
3358 g_assert (addresses [reg]);
3359 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3361 case LLVMArgGsharedvtVariable:
3362 g_assert (addresses [reg]);
3363 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3366 g_assert (args [pindex]);
3367 if (i == 0 && sig->hasthis)
3368 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3370 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3373 g_assert (pindex <= nargs);
3378 // FIXME: Align call sites
3384 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3387 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3389 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3390 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3392 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3393 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3394 if (!sig->pinvoke && !cfg->llvm_only)
3395 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3397 mono_llvm_set_call_preserveall_cc (lcall);
3399 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3400 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3401 if (!ctx->llvm_only && call->rgctx_arg_reg)
3402 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3403 if (call->imt_arg_reg)
3404 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3406 /* Add byval attributes if needed */
3407 for (i = 0; i < sig->param_count; ++i) {
3408 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3410 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3411 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3415 * Convert the result
3417 switch (cinfo->ret.storage) {
3418 case LLVMArgVtypeInReg: {
3419 LLVMValueRef regs [2];
3421 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3425 if (!addresses [ins->dreg])
3426 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3428 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3429 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3430 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3431 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3434 case LLVMArgVtypeByVal:
3435 if (!addresses [call->inst.dreg])
3436 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3437 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3439 case LLVMArgFpStruct:
3440 if (!addresses [call->inst.dreg])
3441 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3442 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3444 case LLVMArgVtypeAsScalar:
3445 if (!addresses [call->inst.dreg])
3446 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3447 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3449 case LLVMArgVtypeRetAddr:
3450 case LLVMArgVtypeByRef:
3451 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3452 /* Some opcodes like STOREX_MEMBASE access these by value */
3453 g_assert (addresses [call->inst.dreg]);
3454 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3457 case LLVMArgScalarRetAddr:
3458 /* Normal scalar returned using a vtype return argument */
3459 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3461 case LLVMArgGsharedvtVariable:
3463 case LLVMArgGsharedvtFixed:
3464 case LLVMArgGsharedvtFixedVtype:
3465 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3468 if (sig->ret->type != MONO_TYPE_VOID)
3469 /* If the method returns an unsigned value, need to zext it */
3470 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));
3474 *builder_ref = ctx->builder;
3478 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3480 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3481 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3483 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3486 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3488 if (ctx->cfg->compile_aot) {
3489 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3491 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3492 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3493 mono_memory_barrier ();
3496 ctx->module->rethrow = callee;
3498 ctx->module->throw_icall = callee;
3502 LLVMValueRef args [2];
3504 args [0] = convert (ctx, exc, exc_type);
3505 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3507 LLVMBuildUnreachable (ctx->builder);
3509 ctx->builder = create_builder (ctx);
3513 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3515 MonoMethodSignature *throw_sig;
3516 LLVMValueRef callee, arg;
3517 const char *icall_name;
3519 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3520 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3523 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3524 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3525 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3526 if (ctx->cfg->compile_aot) {
3527 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3529 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3533 * LLVM doesn't push the exception argument, so we need a different
3536 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3538 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3542 mono_memory_barrier ();
3544 ctx->module->rethrow = callee;
3546 ctx->module->throw_icall = callee;
3548 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3549 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3553 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3555 const char *icall_name = "mono_llvm_resume_exception";
3556 LLVMValueRef callee = ctx->module->resume_eh;
3558 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3561 if (ctx->cfg->compile_aot) {
3562 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3564 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3565 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3566 mono_memory_barrier ();
3568 ctx->module->resume_eh = callee;
3572 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3574 LLVMBuildUnreachable (ctx->builder);
3576 ctx->builder = create_builder (ctx);
3580 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3582 const char *icall_name = "mono_llvm_clear_exception";
3584 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3585 LLVMValueRef callee = NULL;
3588 if (ctx->cfg->compile_aot) {
3589 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3591 // FIXME: This is broken.
3592 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3596 g_assert (builder && callee);
3598 return LLVMBuildCall (builder, callee, NULL, 0, "");
3602 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3604 const char *icall_name = "mono_llvm_load_exception";
3606 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3607 LLVMValueRef callee = NULL;
3610 if (ctx->cfg->compile_aot) {
3611 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3613 // FIXME: This is broken.
3614 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3618 g_assert (builder && callee);
3620 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3625 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3627 const char *icall_name = "mono_llvm_match_exception";
3629 ctx->builder = builder;
3631 const int num_args = 5;
3632 LLVMValueRef args [num_args];
3633 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3634 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3635 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3636 if (ctx->cfg->rgctx_var) {
3637 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3638 g_assert (rgctx_alloc);
3639 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3641 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3644 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3646 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3648 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3649 LLVMValueRef callee = ctx->module->match_exc;
3652 if (ctx->cfg->compile_aot) {
3653 ctx->builder = builder;
3654 // get_callee expects ctx->builder to be the emitting builder
3655 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3657 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3658 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3659 ctx->module->match_exc = callee;
3660 mono_memory_barrier ();
3664 g_assert (builder && callee);
3666 g_assert (ctx->ex_var);
3668 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3671 // FIXME: This won't work because the code-finding makes this
3673 /*#define MONO_PERSONALITY_DEBUG*/
3675 #ifdef MONO_PERSONALITY_DEBUG
3676 static const gboolean use_debug_personality = TRUE;
3677 static const char *default_personality_name = "mono_debug_personality";
3679 static const gboolean use_debug_personality = FALSE;
3680 static const char *default_personality_name = "__gxx_personality_v0";
3684 default_cpp_lpad_exc_signature (void)
3686 static gboolean inited = FALSE;
3687 static LLVMTypeRef sig;
3690 LLVMTypeRef signature [2];
3691 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3692 signature [1] = LLVMInt32Type ();
3693 sig = LLVMStructType (signature, 2, FALSE);
3701 get_mono_personality (EmitContext *ctx)
3703 LLVMValueRef personality = NULL;
3704 static gint32 mapping_inited = FALSE;
3705 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3707 if (!use_debug_personality) {
3708 if (ctx->cfg->compile_aot) {
3709 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3710 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3711 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3712 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3715 if (ctx->cfg->compile_aot) {
3716 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3718 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3719 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3720 mono_memory_barrier ();
3724 g_assert (personality);
3728 static LLVMBasicBlockRef
3729 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3731 MonoCompile *cfg = ctx->cfg;
3732 LLVMBuilderRef old_builder = ctx->builder;
3733 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3735 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3736 ctx->builder = lpadBuilder;
3738 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3739 g_assert (handler_bb);
3741 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3742 LLVMValueRef personality = get_mono_personality (ctx);
3743 g_assert (personality);
3745 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3746 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3748 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3749 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3750 g_assert (landing_pad);
3752 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3753 LLVMAddClause (landing_pad, cast);
3755 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3756 LLVMBuilderRef resume_builder = create_builder (ctx);
3757 ctx->builder = resume_builder;
3758 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3760 emit_resume_eh (ctx, handler_bb);
3763 ctx->builder = lpadBuilder;
3764 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3766 gboolean finally_only = TRUE;
3768 MonoExceptionClause *group_cursor = group_start;
3770 for (int i = 0; i < group_size; i ++) {
3771 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3772 finally_only = FALSE;
3778 // Handle landing pad inlining
3780 if (!finally_only) {
3781 // So at each level of the exception stack we will match the exception again.
3782 // During that match, we need to compare against the handler types for the current
3783 // protected region. We send the try start and end so that we can only check against
3784 // handlers for this lexical protected region.
3785 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3787 // if returns -1, resume
3788 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3790 // else move to that target bb
3791 for (int i=0; i < group_size; i++) {
3792 MonoExceptionClause *clause = group_start + i;
3793 int clause_index = clause - cfg->header->clauses;
3794 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3795 g_assert (handler_bb);
3796 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3797 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3800 int clause_index = group_start - cfg->header->clauses;
3801 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3802 g_assert (finally_bb);
3804 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3807 ctx->builder = old_builder;
3814 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3816 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3817 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3819 // Make exception available to catch blocks
3820 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3821 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3823 g_assert (ctx->ex_var);
3824 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3826 if (bb->in_scount == 1) {
3827 MonoInst *exvar = bb->in_stack [0];
3828 g_assert (!ctx->values [exvar->dreg]);
3829 g_assert (ctx->ex_var);
3830 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3831 emit_volatile_store (ctx, exvar->dreg);
3834 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3837 LLVMBuilderRef handler_builder = create_builder (ctx);
3838 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3839 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3841 // Make the handler code end with a jump to cbb
3842 LLVMBuildBr (handler_builder, cbb);
3846 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3848 MonoCompile *cfg = ctx->cfg;
3849 LLVMValueRef *values = ctx->values;
3850 LLVMModuleRef lmodule = ctx->lmodule;
3851 BBInfo *bblocks = ctx->bblocks;
3853 LLVMValueRef personality;
3854 LLVMValueRef landing_pad;
3855 LLVMBasicBlockRef target_bb;
3857 static gint32 mapping_inited;
3858 static int ti_generator;
3861 LLVMValueRef type_info;
3865 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3867 if (cfg->compile_aot) {
3868 /* Use a dummy personality function */
3869 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3870 g_assert (personality);
3872 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3873 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3874 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3877 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3879 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3882 * Create the type info
3884 sprintf (ti_name, "type_info_%d", ti_generator);
3887 if (cfg->compile_aot) {
3888 /* decode_eh_frame () in aot-runtime.c will decode this */
3889 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3890 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3893 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3895 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3898 * After the cfg mempool is freed, the type info will point to stale memory,
3899 * but this is not a problem, since we decode it once in exception_cb during
3902 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3903 *(gint32*)ti = clause_index;
3905 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3907 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3911 LLVMTypeRef members [2], ret_type;
3913 members [0] = i8ptr;
3914 members [1] = LLVMInt32Type ();
3915 ret_type = LLVMStructType (members, 2, FALSE);
3917 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3918 LLVMAddClause (landing_pad, type_info);
3920 /* Store the exception into the exvar */
3922 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3926 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3927 * code expects control to be transferred to this landing pad even in the
3928 * presence of nested clauses. The landing pad needs to branch to the landing
3929 * pads belonging to nested clauses based on the selector value returned by
3930 * the landing pad instruction, which is passed to the landing pad in a
3931 * register by the EH code.
3933 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3934 g_assert (target_bb);
3937 * Branch to the correct landing pad
3939 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3940 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3942 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3943 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3944 MonoBasicBlock *handler_bb;
3946 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3947 g_assert (handler_bb);
3949 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3950 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3953 /* Start a new bblock which CALL_HANDLER can branch to */
3954 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3956 ctx->builder = builder = create_builder (ctx);
3957 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3959 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3961 /* Store the exception into the IL level exvar */
3962 if (bb->in_scount == 1) {
3963 g_assert (bb->in_scount == 1);
3964 exvar = bb->in_stack [0];
3966 // FIXME: This is shared with filter clauses ?
3967 g_assert (!values [exvar->dreg]);
3969 g_assert (ctx->ex_var);
3970 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3971 emit_volatile_store (ctx, exvar->dreg);
3977 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3979 MonoCompile *cfg = ctx->cfg;
3980 MonoMethodSignature *sig = ctx->sig;
3981 LLVMValueRef method = ctx->lmethod;
3982 LLVMValueRef *values = ctx->values;
3983 LLVMValueRef *addresses = ctx->addresses;
3984 LLVMCallInfo *linfo = ctx->linfo;
3985 LLVMModuleRef lmodule = ctx->lmodule;
3986 BBInfo *bblocks = ctx->bblocks;
3988 LLVMBasicBlockRef cbb;
3989 LLVMBuilderRef builder, starting_builder;
3990 gboolean has_terminator;
3992 LLVMValueRef lhs, rhs;
3995 cbb = get_end_bb (ctx, bb);
3997 builder = create_builder (ctx);
3998 ctx->builder = builder;
3999 LLVMPositionBuilderAtEnd (builder, cbb);
4004 if (bb->flags & BB_EXCEPTION_HANDLER) {
4005 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4006 set_failure (ctx, "handler without invokes");
4011 emit_llvmonly_handler_start (ctx, bb, cbb);
4013 emit_handler_start (ctx, bb, builder);
4016 builder = ctx->builder;
4019 has_terminator = FALSE;
4020 starting_builder = builder;
4021 for (ins = bb->code; ins; ins = ins->next) {
4022 const char *spec = LLVM_INS_INFO (ins->opcode);
4024 char dname_buf [128];
4026 emit_dbg_loc (ctx, builder, ins->cil_code);
4031 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4032 * Start a new bblock. If the llvm optimization passes merge these, we
4033 * can work around that by doing a volatile load + cond branch from
4034 * localloc-ed memory.
4036 //set_failure (ctx, "basic block too long");
4037 cbb = gen_bb (ctx, "CONT_LONG_BB");
4038 LLVMBuildBr (ctx->builder, cbb);
4039 ctx->builder = builder = create_builder (ctx);
4040 LLVMPositionBuilderAtEnd (builder, cbb);
4041 ctx->bblocks [bb->block_num].end_bblock = cbb;
4046 /* There could be instructions after a terminator, skip them */
4049 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4050 sprintf (dname_buf, "t%d", ins->dreg);
4054 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4055 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4057 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4058 lhs = emit_volatile_load (ctx, ins->sreg1);
4060 /* It is ok for SETRET to have an uninitialized argument */
4061 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4062 set_failure (ctx, "sreg1");
4065 lhs = values [ins->sreg1];
4071 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4072 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4073 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4074 rhs = emit_volatile_load (ctx, ins->sreg2);
4076 if (!values [ins->sreg2]) {
4077 set_failure (ctx, "sreg2");
4080 rhs = values [ins->sreg2];
4086 //mono_print_ins (ins);
4087 switch (ins->opcode) {
4090 case OP_LIVERANGE_START:
4091 case OP_LIVERANGE_END:
4094 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4097 #if SIZEOF_VOID_P == 4
4098 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4100 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4104 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4108 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4110 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4112 case OP_DUMMY_ICONST:
4113 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4115 case OP_DUMMY_I8CONST:
4116 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4118 case OP_DUMMY_R8CONST:
4119 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4122 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4123 LLVMBuildBr (builder, target_bb);
4124 has_terminator = TRUE;
4131 LLVMBasicBlockRef new_bb;
4132 LLVMBuilderRef new_builder;
4134 // The default branch is already handled
4135 // FIXME: Handle it here
4137 /* Start new bblock */
4138 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4139 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4141 lhs = convert (ctx, lhs, LLVMInt32Type ());
4142 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4143 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4144 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4146 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4149 new_builder = create_builder (ctx);
4150 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4151 LLVMBuildUnreachable (new_builder);
4153 has_terminator = TRUE;
4154 g_assert (!ins->next);
4160 switch (linfo->ret.storage) {
4161 case LLVMArgVtypeInReg: {
4162 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4163 LLVMValueRef val, addr, retval;
4166 retval = LLVMGetUndef (ret_type);
4168 if (!addresses [ins->sreg1]) {
4170 * The return type is an LLVM vector type, have to convert between it and the
4171 * real return type which is a struct type.
4173 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4174 /* Convert to 2xi64 first */
4175 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4177 for (i = 0; i < 2; ++i) {
4178 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4179 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4181 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4185 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4186 for (i = 0; i < 2; ++i) {
4187 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4188 LLVMValueRef indexes [2], part_addr;
4190 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4191 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4192 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4194 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4196 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4200 LLVMBuildRet (builder, retval);
4203 case LLVMArgVtypeAsScalar: {
4204 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4205 LLVMValueRef retval;
4207 g_assert (addresses [ins->sreg1]);
4209 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4210 LLVMBuildRet (builder, retval);
4213 case LLVMArgVtypeByVal: {
4214 LLVMValueRef retval;
4216 g_assert (addresses [ins->sreg1]);
4217 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4218 LLVMBuildRet (builder, retval);
4221 case LLVMArgVtypeByRef: {
4222 LLVMBuildRetVoid (builder);
4225 case LLVMArgGsharedvtFixed: {
4226 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4227 /* The return value is in lhs, need to store to the vret argument */
4228 /* sreg1 might not be set */
4230 g_assert (cfg->vret_addr);
4231 g_assert (values [cfg->vret_addr->dreg]);
4232 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4234 LLVMBuildRetVoid (builder);
4237 case LLVMArgGsharedvtFixedVtype: {
4239 LLVMBuildRetVoid (builder);
4242 case LLVMArgGsharedvtVariable: {
4244 LLVMBuildRetVoid (builder);
4247 case LLVMArgVtypeRetAddr: {
4248 LLVMBuildRetVoid (builder);
4251 case LLVMArgScalarRetAddr: {
4252 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4253 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4255 /* sreg1 might not be set */
4257 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4258 LLVMBuildRetVoid (builder);
4261 case LLVMArgFpStruct: {
4262 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4263 LLVMValueRef retval;
4265 g_assert (addresses [ins->sreg1]);
4266 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4267 LLVMBuildRet (builder, retval);
4271 case LLVMArgNormal: {
4272 if (!lhs || ctx->is_dead [ins->sreg1]) {
4274 * The method did not set its return value, probably because it
4275 * ends with a throw.
4278 LLVMBuildRetVoid (builder);
4280 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4282 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4284 has_terminator = TRUE;
4288 g_assert_not_reached ();
4297 case OP_ICOMPARE_IMM:
4298 case OP_LCOMPARE_IMM:
4299 case OP_COMPARE_IMM: {
4301 LLVMValueRef cmp, args [16];
4302 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4304 if (ins->next->opcode == OP_NOP)
4307 if (ins->next->opcode == OP_BR)
4308 /* The comparison result is not needed */
4311 rel = mono_opcode_to_cond (ins->next->opcode);
4313 if (ins->opcode == OP_ICOMPARE_IMM) {
4314 lhs = convert (ctx, lhs, LLVMInt32Type ());
4315 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4317 if (ins->opcode == OP_LCOMPARE_IMM) {
4318 lhs = convert (ctx, lhs, LLVMInt64Type ());
4319 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4321 if (ins->opcode == OP_LCOMPARE) {
4322 lhs = convert (ctx, lhs, LLVMInt64Type ());
4323 rhs = convert (ctx, rhs, LLVMInt64Type ());
4325 if (ins->opcode == OP_ICOMPARE) {
4326 lhs = convert (ctx, lhs, LLVMInt32Type ());
4327 rhs = convert (ctx, rhs, LLVMInt32Type ());
4331 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4332 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4333 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4334 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4337 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4338 if (ins->opcode == OP_FCOMPARE) {
4339 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4340 } else if (ins->opcode == OP_RCOMPARE) {
4341 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4342 } else if (ins->opcode == OP_COMPARE_IMM) {
4343 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4344 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4346 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4347 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4348 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4349 /* The immediate is encoded in two fields */
4350 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4351 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4353 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4356 else if (ins->opcode == OP_COMPARE) {
4357 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4358 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4360 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4362 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4366 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4367 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4370 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4371 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4373 * If the target bb contains PHI instructions, LLVM requires
4374 * two PHI entries for this bblock, while we only generate one.
4375 * So convert this to an unconditional bblock. (bxc #171).
4377 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4379 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4381 has_terminator = TRUE;
4382 } else if (MONO_IS_SETCC (ins->next)) {
4383 sprintf (dname_buf, "t%d", ins->next->dreg);
4385 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4387 /* Add stores for volatile variables */
4388 emit_volatile_store (ctx, ins->next->dreg);
4389 } else if (MONO_IS_COND_EXC (ins->next)) {
4390 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4393 builder = ctx->builder;
4395 set_failure (ctx, "next");
4413 rel = mono_opcode_to_cond (ins->opcode);
4415 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4416 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4427 rel = mono_opcode_to_cond (ins->opcode);
4429 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4430 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4438 gboolean empty = TRUE;
4440 /* Check that all input bblocks really branch to us */
4441 for (i = 0; i < bb->in_count; ++i) {
4442 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4443 ins->inst_phi_args [i + 1] = -1;
4449 /* LLVM doesn't like phi instructions with zero operands */
4450 ctx->is_dead [ins->dreg] = TRUE;
4454 /* Created earlier, insert it now */
4455 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4457 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4458 int sreg1 = ins->inst_phi_args [i + 1];
4462 * Count the number of times the incoming bblock branches to us,
4463 * since llvm requires a separate entry for each.
4465 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4466 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4469 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4470 if (switch_ins->inst_many_bb [j] == bb)
4477 /* Remember for later */
4478 for (j = 0; j < count; ++j) {
4479 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4482 node->in_bb = bb->in_bb [i];
4484 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);
4494 values [ins->dreg] = lhs;
4498 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4501 values [ins->dreg] = lhs;
4503 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4505 * This is added by the spilling pass in case of the JIT,
4506 * but we have to do it ourselves.
4508 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4512 case OP_MOVE_F_TO_I4: {
4513 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4516 case OP_MOVE_I4_TO_F: {
4517 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4520 case OP_MOVE_F_TO_I8: {
4521 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4524 case OP_MOVE_I8_TO_F: {
4525 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4558 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4559 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4561 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4564 builder = ctx->builder;
4566 switch (ins->opcode) {
4569 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4573 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4577 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4581 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4585 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4589 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4593 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4597 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4601 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4605 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4609 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4613 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4617 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4621 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4625 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4628 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4631 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4635 g_assert_not_reached ();
4642 lhs = convert (ctx, lhs, LLVMFloatType ());
4643 rhs = convert (ctx, rhs, LLVMFloatType ());
4644 switch (ins->opcode) {
4646 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4649 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4652 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4655 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4658 g_assert_not_reached ();
4667 case OP_IREM_UN_IMM:
4669 case OP_IDIV_UN_IMM:
4675 case OP_ISHR_UN_IMM:
4685 case OP_LSHR_UN_IMM:
4691 case OP_SHR_UN_IMM: {
4694 if (spec [MONO_INST_SRC1] == 'l') {
4695 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4697 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4700 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4703 builder = ctx->builder;
4705 #if SIZEOF_VOID_P == 4
4706 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4707 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4710 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4711 lhs = convert (ctx, lhs, IntPtrType ());
4712 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4713 switch (ins->opcode) {
4717 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4721 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4726 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4730 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4732 case OP_IDIV_UN_IMM:
4733 case OP_LDIV_UN_IMM:
4734 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4738 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4740 case OP_IREM_UN_IMM:
4741 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4746 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4750 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4754 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4759 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4764 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4766 case OP_ISHR_UN_IMM:
4767 /* This is used to implement conv.u4, so the lhs could be an i8 */
4768 lhs = convert (ctx, lhs, LLVMInt32Type ());
4769 imm = convert (ctx, imm, LLVMInt32Type ());
4770 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4772 case OP_LSHR_UN_IMM:
4774 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4777 g_assert_not_reached ();
4782 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4785 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4788 lhs = convert (ctx, lhs, LLVMDoubleType ());
4789 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4792 lhs = convert (ctx, lhs, LLVMFloatType ());
4793 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4796 guint32 v = 0xffffffff;
4797 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4801 guint64 v = 0xffffffffffffffffLL;
4802 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4805 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4807 LLVMValueRef v1, v2;
4809 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4810 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4811 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4816 case OP_ICONV_TO_I1:
4817 case OP_ICONV_TO_I2:
4818 case OP_ICONV_TO_I4:
4819 case OP_ICONV_TO_U1:
4820 case OP_ICONV_TO_U2:
4821 case OP_ICONV_TO_U4:
4822 case OP_LCONV_TO_I1:
4823 case OP_LCONV_TO_I2:
4824 case OP_LCONV_TO_U1:
4825 case OP_LCONV_TO_U2:
4826 case OP_LCONV_TO_U4: {
4829 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);
4831 /* Have to do two casts since our vregs have type int */
4832 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4834 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4836 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4839 case OP_ICONV_TO_I8:
4840 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4842 case OP_ICONV_TO_U8:
4843 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4845 case OP_FCONV_TO_I4:
4846 case OP_RCONV_TO_I4:
4847 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4849 case OP_FCONV_TO_I1:
4850 case OP_RCONV_TO_I1:
4851 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4853 case OP_FCONV_TO_U1:
4854 case OP_RCONV_TO_U1:
4855 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4857 case OP_FCONV_TO_I2:
4858 case OP_RCONV_TO_I2:
4859 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4861 case OP_FCONV_TO_U2:
4862 case OP_RCONV_TO_U2:
4863 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4865 case OP_RCONV_TO_U4:
4866 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4868 case OP_FCONV_TO_I8:
4869 case OP_RCONV_TO_I8:
4870 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4873 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4875 case OP_ICONV_TO_R8:
4876 case OP_LCONV_TO_R8:
4877 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4879 case OP_ICONV_TO_R_UN:
4880 case OP_LCONV_TO_R_UN:
4881 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4883 #if SIZEOF_VOID_P == 4
4886 case OP_LCONV_TO_I4:
4887 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4889 case OP_ICONV_TO_R4:
4890 case OP_LCONV_TO_R4:
4891 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4893 values [ins->dreg] = v;
4895 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4897 case OP_FCONV_TO_R4:
4898 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4900 values [ins->dreg] = v;
4902 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4904 case OP_RCONV_TO_R8:
4905 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4907 case OP_RCONV_TO_R4:
4908 values [ins->dreg] = lhs;
4911 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4914 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4917 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4919 case OP_LOCALLOC_IMM: {
4922 guint32 size = ins->inst_imm;
4923 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4925 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4927 if (ins->flags & MONO_INST_INIT) {
4928 LLVMValueRef args [5];
4931 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4932 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4933 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4934 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4935 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4938 values [ins->dreg] = v;
4942 LLVMValueRef v, size;
4944 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), "");
4946 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4948 if (ins->flags & MONO_INST_INIT) {
4949 LLVMValueRef args [5];
4952 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4954 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4955 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4956 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4958 values [ins->dreg] = v;
4962 case OP_LOADI1_MEMBASE:
4963 case OP_LOADU1_MEMBASE:
4964 case OP_LOADI2_MEMBASE:
4965 case OP_LOADU2_MEMBASE:
4966 case OP_LOADI4_MEMBASE:
4967 case OP_LOADU4_MEMBASE:
4968 case OP_LOADI8_MEMBASE:
4969 case OP_LOADR4_MEMBASE:
4970 case OP_LOADR8_MEMBASE:
4971 case OP_LOAD_MEMBASE:
4979 LLVMValueRef base, index, addr;
4981 gboolean sext = FALSE, zext = FALSE;
4982 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4984 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4989 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)) {
4990 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4995 if (ins->inst_offset == 0) {
4997 } else if (ins->inst_offset % size != 0) {
4998 /* Unaligned load */
4999 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5000 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5002 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5003 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5007 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5009 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5011 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5013 * These will signal LLVM that these loads do not alias any stores, and
5014 * they can't fail, allowing them to be hoisted out of loops.
5016 set_invariant_load_flag (values [ins->dreg]);
5017 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5021 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5023 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5024 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5025 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5029 case OP_STOREI1_MEMBASE_REG:
5030 case OP_STOREI2_MEMBASE_REG:
5031 case OP_STOREI4_MEMBASE_REG:
5032 case OP_STOREI8_MEMBASE_REG:
5033 case OP_STORER4_MEMBASE_REG:
5034 case OP_STORER8_MEMBASE_REG:
5035 case OP_STORE_MEMBASE_REG: {
5037 LLVMValueRef index, addr;
5039 gboolean sext = FALSE, zext = FALSE;
5040 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5042 if (!values [ins->inst_destbasereg]) {
5043 set_failure (ctx, "inst_destbasereg");
5047 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5049 if (ins->inst_offset % size != 0) {
5050 /* Unaligned store */
5051 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5052 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5054 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5055 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5057 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5061 case OP_STOREI1_MEMBASE_IMM:
5062 case OP_STOREI2_MEMBASE_IMM:
5063 case OP_STOREI4_MEMBASE_IMM:
5064 case OP_STOREI8_MEMBASE_IMM:
5065 case OP_STORE_MEMBASE_IMM: {
5067 LLVMValueRef index, addr;
5069 gboolean sext = FALSE, zext = FALSE;
5070 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5072 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5074 if (ins->inst_offset % size != 0) {
5075 /* Unaligned store */
5076 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5077 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5079 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5080 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5082 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5087 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5089 case OP_OUTARG_VTRETADDR:
5097 case OP_VOIDCALL_MEMBASE:
5098 case OP_CALL_MEMBASE:
5099 case OP_LCALL_MEMBASE:
5100 case OP_FCALL_MEMBASE:
5101 case OP_RCALL_MEMBASE:
5102 case OP_VCALL_MEMBASE:
5103 case OP_VOIDCALL_REG:
5108 case OP_VCALL_REG: {
5109 process_call (ctx, bb, &builder, ins);
5114 LLVMValueRef indexes [2];
5115 MonoJumpInfo *tmp_ji, *ji;
5116 LLVMValueRef got_entry_addr;
5120 * FIXME: Can't allocate from the cfg mempool since that is freed if
5121 * the LLVM compile fails.
5123 tmp_ji = g_new0 (MonoJumpInfo, 1);
5124 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5125 tmp_ji->data.target = ins->inst_p0;
5127 ji = mono_aot_patch_info_dup (tmp_ji);
5130 ji->next = cfg->patch_info;
5131 cfg->patch_info = ji;
5133 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5134 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5135 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5136 if (!mono_aot_is_shared_got_offset (got_offset)) {
5137 //mono_print_ji (ji);
5139 ctx->has_got_access = TRUE;
5142 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5143 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5144 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5146 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5147 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5149 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5150 if (!cfg->llvm_only)
5151 set_invariant_load_flag (values [ins->dreg]);
5154 case OP_NOT_REACHED:
5155 LLVMBuildUnreachable (builder);
5156 has_terminator = TRUE;
5157 g_assert (bb->block_num < cfg->max_block_num);
5158 ctx->unreachable [bb->block_num] = TRUE;
5159 /* Might have instructions after this */
5161 MonoInst *next = ins->next;
5163 * FIXME: If later code uses the regs defined by these instructions,
5164 * compilation will fail.
5166 MONO_DELETE_INS (bb, next);
5170 MonoInst *var = ins->inst_i0;
5172 if (var->opcode == OP_VTARG_ADDR) {
5173 /* The variable contains the vtype address */
5174 values [ins->dreg] = values [var->dreg];
5175 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5176 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5178 values [ins->dreg] = addresses [var->dreg];
5183 LLVMValueRef args [1];
5185 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5186 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5190 LLVMValueRef args [1];
5192 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5193 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5197 LLVMValueRef args [1];
5199 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5200 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5204 LLVMValueRef args [1];
5206 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5207 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5221 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5222 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5224 switch (ins->opcode) {
5227 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5231 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5235 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5239 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5242 g_assert_not_reached ();
5245 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5248 case OP_ATOMIC_EXCHANGE_I4:
5249 case OP_ATOMIC_EXCHANGE_I8: {
5250 LLVMValueRef args [2];
5253 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5254 t = LLVMInt32Type ();
5256 t = LLVMInt64Type ();
5258 g_assert (ins->inst_offset == 0);
5260 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5261 args [1] = convert (ctx, rhs, t);
5263 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5266 case OP_ATOMIC_ADD_I4:
5267 case OP_ATOMIC_ADD_I8: {
5268 LLVMValueRef args [2];
5271 if (ins->opcode == OP_ATOMIC_ADD_I4)
5272 t = LLVMInt32Type ();
5274 t = LLVMInt64Type ();
5276 g_assert (ins->inst_offset == 0);
5278 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5279 args [1] = convert (ctx, rhs, t);
5280 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5283 case OP_ATOMIC_CAS_I4:
5284 case OP_ATOMIC_CAS_I8: {
5285 LLVMValueRef args [3], val;
5288 if (ins->opcode == OP_ATOMIC_CAS_I4)
5289 t = LLVMInt32Type ();
5291 t = LLVMInt64Type ();
5293 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5295 args [1] = convert (ctx, values [ins->sreg3], t);
5297 args [2] = convert (ctx, values [ins->sreg2], t);
5298 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5299 /* cmpxchg returns a pair */
5300 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5303 case OP_MEMORY_BARRIER: {
5304 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5307 case OP_ATOMIC_LOAD_I1:
5308 case OP_ATOMIC_LOAD_I2:
5309 case OP_ATOMIC_LOAD_I4:
5310 case OP_ATOMIC_LOAD_I8:
5311 case OP_ATOMIC_LOAD_U1:
5312 case OP_ATOMIC_LOAD_U2:
5313 case OP_ATOMIC_LOAD_U4:
5314 case OP_ATOMIC_LOAD_U8:
5315 case OP_ATOMIC_LOAD_R4:
5316 case OP_ATOMIC_LOAD_R8: {
5317 set_failure (ctx, "atomic mono.load intrinsic");
5321 gboolean sext, zext;
5323 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5324 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5325 LLVMValueRef index, addr;
5327 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5332 if (ins->inst_offset != 0) {
5333 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5334 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5339 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5341 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5344 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5346 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5350 case OP_ATOMIC_STORE_I1:
5351 case OP_ATOMIC_STORE_I2:
5352 case OP_ATOMIC_STORE_I4:
5353 case OP_ATOMIC_STORE_I8:
5354 case OP_ATOMIC_STORE_U1:
5355 case OP_ATOMIC_STORE_U2:
5356 case OP_ATOMIC_STORE_U4:
5357 case OP_ATOMIC_STORE_U8:
5358 case OP_ATOMIC_STORE_R4:
5359 case OP_ATOMIC_STORE_R8: {
5360 set_failure (ctx, "atomic mono.store intrinsic");
5364 gboolean sext, zext;
5366 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5367 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5368 LLVMValueRef index, addr, value;
5370 if (!values [ins->inst_destbasereg]) {
5371 set_failure (ctx, "inst_destbasereg");
5375 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5377 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5378 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5379 value = convert (ctx, values [ins->sreg1], t);
5381 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5385 case OP_RELAXED_NOP: {
5386 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5387 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5394 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5396 // 257 == FS segment register
5397 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5399 // 256 == GS segment register
5400 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5403 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5404 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5405 /* See mono_amd64_emit_tls_get () */
5406 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5408 // 256 == GS segment register
5409 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5410 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5412 set_failure (ctx, "opcode tls-get");
5418 case OP_TLS_GET_REG: {
5419 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5420 /* See emit_tls_get_reg () */
5421 // 256 == GS segment register
5422 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5423 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5425 set_failure (ctx, "opcode tls-get");
5431 case OP_TLS_SET_REG: {
5432 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5433 /* See emit_tls_get_reg () */
5434 // 256 == GS segment register
5435 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5436 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5438 set_failure (ctx, "opcode tls-set-reg");
5448 case OP_IADD_OVF_UN:
5450 case OP_ISUB_OVF_UN:
5452 case OP_IMUL_OVF_UN:
5453 #if SIZEOF_VOID_P == 8
5455 case OP_LADD_OVF_UN:
5457 case OP_LSUB_OVF_UN:
5459 case OP_LMUL_OVF_UN:
5462 LLVMValueRef args [2], val, ovf, func;
5464 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5465 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5466 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5468 val = LLVMBuildCall (builder, func, args, 2, "");
5469 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5470 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5471 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5474 builder = ctx->builder;
5480 * We currently model them using arrays. Promotion to local vregs is
5481 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5482 * so we always have an entry in cfg->varinfo for them.
5483 * FIXME: Is this needed ?
5486 MonoClass *klass = ins->klass;
5487 LLVMValueRef args [5];
5491 set_failure (ctx, "!klass");
5495 if (!addresses [ins->dreg])
5496 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5497 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5498 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5499 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5501 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5502 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5503 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5506 case OP_DUMMY_VZERO:
5509 case OP_STOREV_MEMBASE:
5510 case OP_LOADV_MEMBASE:
5512 MonoClass *klass = ins->klass;
5513 LLVMValueRef src = NULL, dst, args [5];
5514 gboolean done = FALSE;
5518 set_failure (ctx, "!klass");
5522 if (mini_is_gsharedvt_klass (klass)) {
5524 set_failure (ctx, "gsharedvt");
5528 switch (ins->opcode) {
5529 case OP_STOREV_MEMBASE:
5530 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5531 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5532 /* Decomposed earlier */
5533 g_assert_not_reached ();
5536 if (!addresses [ins->sreg1]) {
5538 g_assert (values [ins->sreg1]);
5539 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));
5540 LLVMBuildStore (builder, values [ins->sreg1], dst);
5543 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5544 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5547 case OP_LOADV_MEMBASE:
5548 if (!addresses [ins->dreg])
5549 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5550 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5551 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5554 if (!addresses [ins->sreg1])
5555 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5556 if (!addresses [ins->dreg])
5557 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5558 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5559 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5562 g_assert_not_reached ();
5572 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5573 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5575 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5576 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5577 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5580 case OP_LLVM_OUTARG_VT: {
5581 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5582 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5584 if (ainfo->storage == LLVMArgScalarByRef) {
5585 LLVMTypeRef argtype;
5586 LLVMValueRef loc, v;
5588 argtype = type_to_llvm_arg_type (ctx, t);
5589 loc = build_alloca_llvm_type (ctx, argtype, 0);
5590 v = convert (ctx, values [ins->sreg1], argtype);
5591 LLVMBuildStore (ctx->builder, v, loc);
5592 addresses [ins->dreg] = loc;
5593 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5594 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5596 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5597 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5599 g_assert (addresses [ins->sreg1]);
5600 addresses [ins->dreg] = addresses [ins->sreg1];
5602 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5603 if (!addresses [ins->sreg1]) {
5604 addresses [ins->sreg1] = build_alloca (ctx, t);
5605 g_assert (values [ins->sreg1]);
5607 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5608 addresses [ins->dreg] = addresses [ins->sreg1];
5610 if (!addresses [ins->sreg1]) {
5611 addresses [ins->sreg1] = build_alloca (ctx, t);
5612 g_assert (values [ins->sreg1]);
5613 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5615 addresses [ins->dreg] = addresses [ins->sreg1];
5623 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5625 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5628 case OP_LOADX_MEMBASE: {
5629 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5632 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5633 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5636 case OP_STOREX_MEMBASE: {
5637 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5640 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5641 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5648 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5652 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5658 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5662 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5666 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5670 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5673 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5676 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5679 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5683 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5694 LLVMValueRef v = NULL;
5696 switch (ins->opcode) {
5701 t = LLVMVectorType (LLVMInt32Type (), 4);
5702 rt = LLVMVectorType (LLVMFloatType (), 4);
5708 t = LLVMVectorType (LLVMInt64Type (), 2);
5709 rt = LLVMVectorType (LLVMDoubleType (), 2);
5712 t = LLVMInt32Type ();
5713 rt = LLVMInt32Type ();
5714 g_assert_not_reached ();
5717 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5718 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5719 switch (ins->opcode) {
5722 v = LLVMBuildAnd (builder, lhs, rhs, "");
5726 v = LLVMBuildOr (builder, lhs, rhs, "");
5730 v = LLVMBuildXor (builder, lhs, rhs, "");
5734 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5737 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5761 case OP_PADDB_SAT_UN:
5762 case OP_PADDW_SAT_UN:
5763 case OP_PSUBB_SAT_UN:
5764 case OP_PSUBW_SAT_UN:
5772 case OP_PMULW_HIGH_UN: {
5773 LLVMValueRef args [2];
5778 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5785 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5789 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5797 case OP_EXTRACTX_U2:
5799 case OP_EXTRACT_U1: {
5801 gboolean zext = FALSE;
5803 t = simd_op_to_llvm_type (ins->opcode);
5805 switch (ins->opcode) {
5813 case OP_EXTRACTX_U2:
5818 t = LLVMInt32Type ();
5819 g_assert_not_reached ();
5822 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5823 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5825 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5834 case OP_EXPAND_R8: {
5835 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5836 LLVMValueRef mask [16], v;
5839 for (i = 0; i < 16; ++i)
5840 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5842 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5844 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5845 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5850 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5853 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5856 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5859 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5862 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5865 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5876 case OP_EXTRACT_MASK:
5883 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5885 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5891 LLVMValueRef args [3];
5895 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5897 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5902 /* This is only used for implementing shifts by non-immediate */
5903 values [ins->dreg] = lhs;
5914 LLVMValueRef args [3];
5917 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5919 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5930 case OP_PSHLQ_REG: {
5931 LLVMValueRef args [3];
5934 args [1] = values [ins->sreg2];
5936 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5943 case OP_PSHUFLEW_LOW:
5944 case OP_PSHUFLEW_HIGH: {
5946 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5947 int i, mask_size = 0;
5948 int imask = ins->inst_c0;
5950 /* Convert the x86 shuffle mask to LLVM's */
5951 switch (ins->opcode) {
5954 mask [0] = ((imask >> 0) & 3);
5955 mask [1] = ((imask >> 2) & 3);
5956 mask [2] = ((imask >> 4) & 3) + 4;
5957 mask [3] = ((imask >> 6) & 3) + 4;
5958 v1 = values [ins->sreg1];
5959 v2 = values [ins->sreg2];
5963 mask [0] = ((imask >> 0) & 1);
5964 mask [1] = ((imask >> 1) & 1) + 2;
5965 v1 = values [ins->sreg1];
5966 v2 = values [ins->sreg2];
5968 case OP_PSHUFLEW_LOW:
5970 mask [0] = ((imask >> 0) & 3);
5971 mask [1] = ((imask >> 2) & 3);
5972 mask [2] = ((imask >> 4) & 3);
5973 mask [3] = ((imask >> 6) & 3);
5978 v1 = values [ins->sreg1];
5979 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5981 case OP_PSHUFLEW_HIGH:
5987 mask [4] = 4 + ((imask >> 0) & 3);
5988 mask [5] = 4 + ((imask >> 2) & 3);
5989 mask [6] = 4 + ((imask >> 4) & 3);
5990 mask [7] = 4 + ((imask >> 6) & 3);
5991 v1 = values [ins->sreg1];
5992 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5996 mask [0] = ((imask >> 0) & 3);
5997 mask [1] = ((imask >> 2) & 3);
5998 mask [2] = ((imask >> 4) & 3);
5999 mask [3] = ((imask >> 6) & 3);
6000 v1 = values [ins->sreg1];
6001 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6004 g_assert_not_reached ();
6006 for (i = 0; i < mask_size; ++i)
6007 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6009 values [ins->dreg] =
6010 LLVMBuildShuffleVector (builder, v1, v2,
6011 LLVMConstVector (mask_values, mask_size), dname);
6015 case OP_UNPACK_LOWB:
6016 case OP_UNPACK_LOWW:
6017 case OP_UNPACK_LOWD:
6018 case OP_UNPACK_LOWQ:
6019 case OP_UNPACK_LOWPS:
6020 case OP_UNPACK_LOWPD:
6021 case OP_UNPACK_HIGHB:
6022 case OP_UNPACK_HIGHW:
6023 case OP_UNPACK_HIGHD:
6024 case OP_UNPACK_HIGHQ:
6025 case OP_UNPACK_HIGHPS:
6026 case OP_UNPACK_HIGHPD: {
6028 LLVMValueRef mask_values [16];
6029 int i, mask_size = 0;
6030 gboolean low = FALSE;
6032 switch (ins->opcode) {
6033 case OP_UNPACK_LOWB:
6037 case OP_UNPACK_LOWW:
6041 case OP_UNPACK_LOWD:
6042 case OP_UNPACK_LOWPS:
6046 case OP_UNPACK_LOWQ:
6047 case OP_UNPACK_LOWPD:
6051 case OP_UNPACK_HIGHB:
6054 case OP_UNPACK_HIGHW:
6057 case OP_UNPACK_HIGHD:
6058 case OP_UNPACK_HIGHPS:
6061 case OP_UNPACK_HIGHQ:
6062 case OP_UNPACK_HIGHPD:
6066 g_assert_not_reached ();
6070 for (i = 0; i < (mask_size / 2); ++i) {
6072 mask [(i * 2) + 1] = mask_size + i;
6075 for (i = 0; i < (mask_size / 2); ++i) {
6076 mask [(i * 2)] = (mask_size / 2) + i;
6077 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6081 for (i = 0; i < mask_size; ++i)
6082 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6084 values [ins->dreg] =
6085 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6086 LLVMConstVector (mask_values, mask_size), dname);
6091 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6092 LLVMValueRef v, val;
6094 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6095 val = LLVMConstNull (t);
6096 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6097 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6099 values [ins->dreg] = val;
6103 case OP_DUPPS_HIGH: {
6104 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6105 LLVMValueRef v1, v2, val;
6108 if (ins->opcode == OP_DUPPS_LOW) {
6109 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6110 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6112 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6113 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6115 val = LLVMConstNull (t);
6116 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6117 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6118 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6119 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6121 values [ins->dreg] = val;
6131 * EXCEPTION HANDLING
6133 case OP_IMPLICIT_EXCEPTION:
6134 /* This marks a place where an implicit exception can happen */
6135 if (bb->region != -1)
6136 set_failure (ctx, "implicit-exception");
6140 gboolean rethrow = (ins->opcode == OP_RETHROW);
6141 if (ctx->llvm_only) {
6142 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6143 has_terminator = TRUE;
6144 ctx->unreachable [bb->block_num] = TRUE;
6146 emit_throw (ctx, bb, rethrow, lhs);
6147 builder = ctx->builder;
6151 case OP_CALL_HANDLER: {
6153 * We don't 'call' handlers, but instead simply branch to them.
6154 * The code generated by ENDFINALLY will branch back to us.
6156 LLVMBasicBlockRef noex_bb;
6158 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6160 bb_list = info->call_handler_return_bbs;
6163 * Set the indicator variable for the finally clause.
6165 lhs = info->finally_ind;
6167 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6169 /* Branch to the finally clause */
6170 LLVMBuildBr (builder, info->call_handler_target_bb);
6172 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6173 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6175 builder = ctx->builder = create_builder (ctx);
6176 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6178 bblocks [bb->block_num].end_bblock = noex_bb;
6181 case OP_START_HANDLER: {
6184 case OP_ENDFINALLY: {
6185 LLVMBasicBlockRef resume_bb;
6186 MonoBasicBlock *handler_bb;
6187 LLVMValueRef val, switch_ins, callee;
6191 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6192 g_assert (handler_bb);
6193 info = &bblocks [handler_bb->block_num];
6194 lhs = info->finally_ind;
6197 bb_list = info->call_handler_return_bbs;
6199 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6201 /* Load the finally variable */
6202 val = LLVMBuildLoad (builder, lhs, "");
6204 /* Reset the variable */
6205 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6207 /* Branch to either resume_bb, or to the bblocks in bb_list */
6208 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6210 * The other targets are added at the end to handle OP_CALL_HANDLER
6211 * opcodes processed later.
6213 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6215 builder = ctx->builder = create_builder (ctx);
6216 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6218 if (ctx->llvm_only) {
6219 emit_resume_eh (ctx, bb);
6221 if (ctx->cfg->compile_aot) {
6222 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6224 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6226 LLVMBuildCall (builder, callee, NULL, 0, "");
6227 LLVMBuildUnreachable (builder);
6230 has_terminator = TRUE;
6233 case OP_IL_SEQ_POINT:
6238 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6239 set_failure (ctx, reason);
6247 /* Convert the value to the type required by phi nodes */
6248 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6249 if (!values [ins->dreg])
6251 values [ins->dreg] = addresses [ins->dreg];
6253 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6256 /* Add stores for volatile variables */
6257 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6258 emit_volatile_store (ctx, ins->dreg);
6264 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6265 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6268 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6269 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6270 LLVMBuildRetVoid (builder);
6273 if (bb == cfg->bb_entry)
6274 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6278 * mono_llvm_check_method_supported:
6280 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6281 * compiling a method twice.
6284 mono_llvm_check_method_supported (MonoCompile *cfg)
6291 if (cfg->method->save_lmf) {
6292 cfg->exception_message = g_strdup ("lmf");
6293 cfg->disable_llvm = TRUE;
6295 if (cfg->disable_llvm)
6299 * Nested clauses where one of the clauses is a finally clause is
6300 * not supported, because LLVM can't figure out the control flow,
6301 * probably because we resume exception handling by calling our
6302 * own function instead of using the 'resume' llvm instruction.
6304 for (i = 0; i < cfg->header->num_clauses; ++i) {
6305 for (j = 0; j < cfg->header->num_clauses; ++j) {
6306 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6307 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6309 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6310 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6311 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6312 cfg->exception_message = g_strdup ("nested clauses");
6313 cfg->disable_llvm = TRUE;
6318 if (cfg->disable_llvm)
6322 if (cfg->method->dynamic) {
6323 cfg->exception_message = g_strdup ("dynamic.");
6324 cfg->disable_llvm = TRUE;
6326 if (cfg->disable_llvm)
6330 static LLVMCallInfo*
6331 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6333 LLVMCallInfo *linfo;
6336 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6340 * Gsharedvt methods have the following calling convention:
6341 * - all arguments are passed by ref, even non generic ones
6342 * - the return value is returned by ref too, using a vret
6343 * argument passed after 'this'.
6345 n = sig->param_count + sig->hasthis;
6346 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6350 linfo->args [pindex ++].storage = LLVMArgNormal;
6352 if (sig->ret->type != MONO_TYPE_VOID) {
6353 if (mini_is_gsharedvt_variable_type (sig->ret))
6354 linfo->ret.storage = LLVMArgGsharedvtVariable;
6355 else if (mini_type_is_vtype (sig->ret))
6356 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6358 linfo->ret.storage = LLVMArgGsharedvtFixed;
6359 linfo->vret_arg_index = pindex;
6361 linfo->ret.storage = LLVMArgNone;
6364 for (i = 0; i < sig->param_count; ++i) {
6365 if (sig->params [i]->byref)
6366 linfo->args [pindex].storage = LLVMArgNormal;
6367 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6368 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6369 else if (mini_type_is_vtype (sig->params [i]))
6370 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6372 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6373 linfo->args [pindex].type = sig->params [i];
6380 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6381 for (i = 0; i < sig->param_count; ++i)
6382 linfo->args [i + sig->hasthis].type = sig->params [i];
6388 emit_method_inner (EmitContext *ctx);
6391 free_ctx (EmitContext *ctx)
6395 g_free (ctx->values);
6396 g_free (ctx->addresses);
6397 g_free (ctx->vreg_types);
6398 g_free (ctx->vreg_cli_types);
6399 g_free (ctx->is_dead);
6400 g_free (ctx->unreachable);
6401 g_ptr_array_free (ctx->phi_values, TRUE);
6402 g_free (ctx->bblocks);
6403 g_hash_table_destroy (ctx->region_to_handler);
6404 g_hash_table_destroy (ctx->clause_to_handler);
6405 g_free (ctx->method_name);
6406 g_ptr_array_free (ctx->bblock_list, TRUE);
6408 for (l = ctx->builders; l; l = l->next) {
6409 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6410 LLVMDisposeBuilder (builder);
6417 * mono_llvm_emit_method:
6419 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6422 mono_llvm_emit_method (MonoCompile *cfg)
6426 gboolean is_linkonce = FALSE;
6429 /* The code below might acquire the loader lock, so use it for global locking */
6430 mono_loader_lock ();
6432 /* Used to communicate with the callbacks */
6433 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6435 ctx = g_new0 (EmitContext, 1);
6437 ctx->mempool = cfg->mempool;
6440 * This maps vregs to the LLVM instruction defining them
6442 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6444 * This maps vregs for volatile variables to the LLVM instruction defining their
6447 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6448 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6449 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6450 ctx->phi_values = g_ptr_array_sized_new (256);
6452 * This signals whenever the vreg was defined by a phi node with no input vars
6453 * (i.e. all its input bblocks end with NOT_REACHABLE).
6455 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6456 /* Whenever the bblock is unreachable */
6457 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6458 ctx->bblock_list = g_ptr_array_sized_new (256);
6460 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6461 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6462 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6463 if (cfg->compile_aot) {
6464 ctx->module = &aot_module;
6468 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6469 * linkage for them. This requires the following:
6470 * - the method needs to have a unique mangled name
6471 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6473 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6475 method_name = mono_aot_get_mangled_method_name (cfg->method);
6477 is_linkonce = FALSE;
6480 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6482 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6486 method_name = mono_aot_get_method_name (cfg);
6487 cfg->llvm_method_name = g_strdup (method_name);
6489 init_jit_module (cfg->domain);
6490 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6491 method_name = mono_method_full_name (cfg->method, TRUE);
6493 ctx->method_name = method_name;
6494 ctx->is_linkonce = is_linkonce;
6496 ctx->lmodule = ctx->module->lmodule;
6497 ctx->llvm_only = ctx->module->llvm_only;
6499 emit_method_inner (ctx);
6501 if (!ctx_ok (ctx)) {
6503 /* Need to add unused phi nodes as they can be referenced by other values */
6504 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6505 LLVMBuilderRef builder;
6507 builder = create_builder (ctx);
6508 LLVMPositionBuilderAtEnd (builder, phi_bb);
6510 for (i = 0; i < ctx->phi_values->len; ++i) {
6511 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6512 if (LLVMGetInstructionParent (v) == NULL)
6513 LLVMInsertIntoBuilder (builder, v);
6516 LLVMDeleteFunction (ctx->lmethod);
6522 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6524 mono_loader_unlock ();
6528 emit_method_inner (EmitContext *ctx)
6530 MonoCompile *cfg = ctx->cfg;
6531 MonoMethodSignature *sig;
6533 LLVMTypeRef method_type;
6534 LLVMValueRef method = NULL;
6535 LLVMValueRef *values = ctx->values;
6536 int i, max_block_num, bb_index;
6537 gboolean last = FALSE;
6538 LLVMCallInfo *linfo;
6539 LLVMModuleRef lmodule = ctx->lmodule;
6541 GPtrArray *bblock_list = ctx->bblock_list;
6542 MonoMethodHeader *header;
6543 MonoExceptionClause *clause;
6546 if (cfg->gsharedvt && !cfg->llvm_only) {
6547 set_failure (ctx, "gsharedvt");
6553 static int count = 0;
6556 if (g_getenv ("LLVM_COUNT")) {
6557 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6558 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6562 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6563 set_failure (ctx, "count");
6570 sig = mono_method_signature (cfg->method);
6573 linfo = get_llvm_call_info (cfg, sig);
6579 linfo->rgctx_arg = TRUE;
6580 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6584 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6585 ctx->lmethod = method;
6587 if (!cfg->llvm_only)
6588 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6589 LLVMSetLinkage (method, LLVMPrivateLinkage);
6591 LLVMAddFunctionAttr (method, LLVMUWTable);
6593 if (cfg->compile_aot) {
6594 LLVMSetLinkage (method, LLVMInternalLinkage);
6595 if (ctx->module->external_symbols) {
6596 LLVMSetLinkage (method, LLVMExternalLinkage);
6597 LLVMSetVisibility (method, LLVMHiddenVisibility);
6599 if (ctx->is_linkonce) {
6600 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6601 LLVMSetVisibility (method, LLVMDefaultVisibility);
6604 LLVMSetLinkage (method, LLVMPrivateLinkage);
6607 if (cfg->method->save_lmf && !cfg->llvm_only) {
6608 set_failure (ctx, "lmf");
6612 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6613 set_failure (ctx, "pinvoke signature");
6617 header = cfg->header;
6618 for (i = 0; i < header->num_clauses; ++i) {
6619 clause = &header->clauses [i];
6620 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6621 set_failure (ctx, "non-finally/catch clause.");
6625 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6626 /* We can't handle inlined methods with clauses */
6627 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6629 if (linfo->rgctx_arg) {
6630 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6631 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6633 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6634 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6635 * CC_X86_64_Mono in X86CallingConv.td.
6637 if (!ctx->llvm_only)
6638 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6639 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6641 ctx->rgctx_arg_pindex = -1;
6643 if (cfg->vret_addr) {
6644 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6645 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6646 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6647 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6648 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6650 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6651 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6652 LLVMSetValueName (param, "vret");
6656 ctx->this_arg_pindex = linfo->this_arg_pindex;
6657 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6658 values [cfg->args [0]->dreg] = ctx->this_arg;
6659 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6662 names = g_new (char *, sig->param_count);
6663 mono_method_get_param_names (cfg->method, (const char **) names);
6665 for (i = 0; i < sig->param_count; ++i) {
6666 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6668 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6671 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6672 name = g_strdup_printf ("dummy_%d_%d", i, j);
6673 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6677 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6678 if (ainfo->storage == LLVMArgScalarByRef) {
6679 if (names [i] && names [i][0] != '\0')
6680 name = g_strdup_printf ("p_arg_%s", names [i]);
6682 name = g_strdup_printf ("p_arg_%d", i);
6683 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6684 if (names [i] && names [i][0] != '\0')
6685 name = g_strdup_printf ("p_arg_%s", names [i]);
6687 name = g_strdup_printf ("p_arg_%d", i);
6689 if (names [i] && names [i][0] != '\0')
6690 name = g_strdup_printf ("arg_%s", names [i]);
6692 name = g_strdup_printf ("arg_%d", i);
6694 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6696 if (ainfo->storage == LLVMArgVtypeByVal)
6697 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6699 if (ainfo->storage == LLVMArgVtypeByRef) {
6701 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6706 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6707 ctx->minfo = mono_debug_lookup_method (cfg->method);
6708 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6712 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6713 max_block_num = MAX (max_block_num, bb->block_num);
6714 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6716 /* Add branches between non-consecutive bblocks */
6717 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6718 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6719 bb->next_bb != bb->last_ins->inst_false_bb) {
6721 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6722 inst->opcode = OP_BR;
6723 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6724 mono_bblock_add_inst (bb, inst);
6729 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6730 * was later optimized away, so clear these flags, and add them back for the still
6731 * present OP_LDADDR instructions.
6733 for (i = 0; i < cfg->next_vreg; ++i) {
6736 ins = get_vreg_to_inst (cfg, i);
6737 if (ins && ins != cfg->rgctx_var)
6738 ins->flags &= ~MONO_INST_INDIRECT;
6742 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6744 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6746 LLVMBuilderRef builder;
6748 char dname_buf[128];
6750 builder = create_builder (ctx);
6752 for (ins = bb->code; ins; ins = ins->next) {
6753 switch (ins->opcode) {
6758 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6763 if (ins->opcode == OP_VPHI) {
6764 /* Treat valuetype PHI nodes as operating on the address itself */
6765 g_assert (ins->klass);
6766 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6770 * Have to precreate these, as they can be referenced by
6771 * earlier instructions.
6773 sprintf (dname_buf, "t%d", ins->dreg);
6775 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6777 if (ins->opcode == OP_VPHI)
6778 ctx->addresses [ins->dreg] = values [ins->dreg];
6780 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6783 * Set the expected type of the incoming arguments since these have
6784 * to have the same type.
6786 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6787 int sreg1 = ins->inst_phi_args [i + 1];
6790 ctx->vreg_types [sreg1] = phi_type;
6795 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6804 * Create an ordering for bblocks, use the depth first order first, then
6805 * put the exception handling bblocks last.
6807 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6808 bb = cfg->bblocks [bb_index];
6809 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6810 g_ptr_array_add (bblock_list, bb);
6811 bblocks [bb->block_num].added = TRUE;
6815 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6816 if (!bblocks [bb->block_num].added)
6817 g_ptr_array_add (bblock_list, bb);
6821 * Second pass: generate code.
6824 LLVMBuilderRef entry_builder = create_builder (ctx);
6825 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6826 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6827 emit_entry_bb (ctx, entry_builder);
6829 // Make landing pads first
6830 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6832 if (ctx->llvm_only) {
6833 size_t group_index = 0;
6834 while (group_index < cfg->header->num_clauses) {
6836 size_t cursor = group_index;
6837 while (cursor < cfg->header->num_clauses &&
6838 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6839 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6844 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6845 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6846 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6848 group_index = cursor;
6852 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6853 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6855 // Prune unreachable mono BBs.
6856 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6859 process_bb (ctx, bb);
6863 g_hash_table_destroy (ctx->exc_meta);
6865 mono_memory_barrier ();
6867 /* Add incoming phi values */
6868 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6869 GSList *l, *ins_list;
6871 ins_list = bblocks [bb->block_num].phi_nodes;
6873 for (l = ins_list; l; l = l->next) {
6874 PhiNode *node = (PhiNode*)l->data;
6875 MonoInst *phi = node->phi;
6876 int sreg1 = node->sreg;
6877 LLVMBasicBlockRef in_bb;
6882 in_bb = get_end_bb (ctx, node->in_bb);
6884 if (ctx->unreachable [node->in_bb->block_num])
6887 if (!values [sreg1]) {
6888 /* Can happen with values in EH clauses */
6889 set_failure (ctx, "incoming phi sreg1");
6893 if (phi->opcode == OP_VPHI) {
6894 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6895 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6897 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6898 set_failure (ctx, "incoming phi arg type mismatch");
6901 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6902 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6907 /* Nullify empty phi instructions */
6908 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6909 GSList *l, *ins_list;
6911 ins_list = bblocks [bb->block_num].phi_nodes;
6913 for (l = ins_list; l; l = l->next) {
6914 PhiNode *node = (PhiNode*)l->data;
6915 MonoInst *phi = node->phi;
6916 LLVMValueRef phi_ins = values [phi->dreg];
6919 /* Already removed */
6922 if (LLVMCountIncoming (phi_ins) == 0) {
6923 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6924 LLVMInstructionEraseFromParent (phi_ins);
6925 values [phi->dreg] = NULL;
6930 /* Create the SWITCH statements for ENDFINALLY instructions */
6931 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6932 BBInfo *info = &bblocks [bb->block_num];
6934 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6935 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6936 GSList *bb_list = info->call_handler_return_bbs;
6938 for (i = 0; i < g_slist_length (bb_list); ++i)
6939 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6943 /* Initialize the method if needed */
6944 if (cfg->compile_aot && ctx->llvm_only) {
6945 // FIXME: Add more shared got entries
6946 ctx->builder = create_builder (ctx);
6947 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6949 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6951 // FIXME: beforefieldinit
6952 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6953 emit_init_method (ctx);
6955 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6959 if (cfg->llvm_only) {
6960 GHashTableIter iter;
6962 GSList *callers, *l, *l2;
6965 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6966 * We can't do this earlier, as it contains llvm instructions which can be
6967 * freed if compilation fails.
6968 * FIXME: Get rid of this when all methods can be llvm compiled.
6970 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6971 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6972 for (l = callers; l; l = l->next) {
6973 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6974 l2 = g_slist_prepend (l2, l->data);
6975 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6980 if (cfg->verbose_level > 1)
6981 mono_llvm_dump_value (method);
6983 if (cfg->compile_aot && !cfg->llvm_only)
6984 mark_as_used (ctx->module, method);
6986 if (cfg->compile_aot && !cfg->llvm_only) {
6987 LLVMValueRef md_args [16];
6988 LLVMValueRef md_node;
6991 method_index = mono_aot_get_method_index (cfg->orig_method);
6992 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6993 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6994 md_node = LLVMMDNode (md_args, 2);
6995 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6996 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6999 if (cfg->compile_aot) {
7000 /* Don't generate native code, keep the LLVM IR */
7001 if (cfg->verbose_level)
7002 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7004 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7005 g_assert (err == 0);
7007 //LLVMVerifyFunction(method, 0);
7008 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7010 if (cfg->verbose_level > 1)
7011 mono_llvm_dump_value (ctx->lmethod);
7013 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7015 /* Set by emit_cb */
7016 g_assert (cfg->code_len);
7019 if (ctx->module->method_to_lmethod)
7020 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7021 if (ctx->module->idx_to_lmethod)
7022 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7024 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7025 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7029 * mono_llvm_create_vars:
7031 * Same as mono_arch_create_vars () for LLVM.
7034 mono_llvm_create_vars (MonoCompile *cfg)
7036 MonoMethodSignature *sig;
7038 sig = mono_method_signature (cfg->method);
7039 if (cfg->gsharedvt && cfg->llvm_only) {
7040 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7041 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7042 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7043 printf ("vret_addr = ");
7044 mono_print_ins (cfg->vret_addr);
7048 mono_arch_create_vars (cfg);
7053 * mono_llvm_emit_call:
7055 * Same as mono_arch_emit_call () for LLVM.
7058 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7061 MonoMethodSignature *sig;
7062 int i, n, stack_size;
7067 sig = call->signature;
7068 n = sig->param_count + sig->hasthis;
7070 call->cinfo = get_llvm_call_info (cfg, sig);
7072 if (cfg->disable_llvm)
7075 if (sig->call_convention == MONO_CALL_VARARG) {
7076 cfg->exception_message = g_strdup ("varargs");
7077 cfg->disable_llvm = TRUE;
7080 for (i = 0; i < n; ++i) {
7083 ainfo = call->cinfo->args + i;
7085 in = call->args [i];
7087 /* Simply remember the arguments */
7088 switch (ainfo->storage) {
7089 case LLVMArgNormal: {
7090 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7093 opcode = mono_type_to_regmove (cfg, t);
7094 if (opcode == OP_FMOVE) {
7095 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7096 ins->dreg = mono_alloc_freg (cfg);
7097 } else if (opcode == OP_LMOVE) {
7098 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7099 ins->dreg = mono_alloc_lreg (cfg);
7100 } else if (opcode == OP_RMOVE) {
7101 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7102 ins->dreg = mono_alloc_freg (cfg);
7104 MONO_INST_NEW (cfg, ins, OP_MOVE);
7105 ins->dreg = mono_alloc_ireg (cfg);
7107 ins->sreg1 = in->dreg;
7110 case LLVMArgVtypeByVal:
7111 case LLVMArgVtypeByRef:
7112 case LLVMArgVtypeInReg:
7113 case LLVMArgVtypeAsScalar:
7114 case LLVMArgScalarByRef:
7115 case LLVMArgAsIArgs:
7116 case LLVMArgAsFpArgs:
7117 case LLVMArgGsharedvtVariable:
7118 case LLVMArgGsharedvtFixed:
7119 case LLVMArgGsharedvtFixedVtype:
7120 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7121 ins->dreg = mono_alloc_ireg (cfg);
7122 ins->sreg1 = in->dreg;
7123 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7124 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7125 ins->inst_vtype = ainfo->type;
7126 ins->klass = mono_class_from_mono_type (ainfo->type);
7129 cfg->exception_message = g_strdup ("ainfo->storage");
7130 cfg->disable_llvm = TRUE;
7134 if (!cfg->disable_llvm) {
7135 MONO_ADD_INS (cfg->cbb, ins);
7136 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7141 static unsigned char*
7142 alloc_cb (LLVMValueRef function, int size)
7146 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7150 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7152 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7157 emitted_cb (LLVMValueRef function, void *start, void *end)
7161 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7163 cfg->code_len = (guint8*)end - (guint8*)start;
7167 exception_cb (void *data)
7170 MonoJitExceptionInfo *ei;
7171 guint32 ei_len, i, j, nested_len, nindex;
7172 gpointer *type_info;
7173 int this_reg, this_offset;
7175 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7179 * data points to a DWARF FDE structure, convert it to our unwind format and
7181 * An alternative would be to save it directly, and modify our unwinder to work
7184 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);
7185 if (cfg->verbose_level > 1)
7186 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7188 /* Count nested clauses */
7190 for (i = 0; i < ei_len; ++i) {
7191 gint32 cindex1 = *(gint32*)type_info [i];
7192 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7194 for (j = 0; j < cfg->header->num_clauses; ++j) {
7196 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7198 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7204 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7205 cfg->llvm_ex_info_len = ei_len + nested_len;
7206 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7207 /* Fill the rest of the information from the type info */
7208 for (i = 0; i < ei_len; ++i) {
7209 gint32 clause_index = *(gint32*)type_info [i];
7210 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7212 cfg->llvm_ex_info [i].flags = clause->flags;
7213 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7214 cfg->llvm_ex_info [i].clause_index = clause_index;
7218 * For nested clauses, the LLVM produced exception info associates the try interval with
7219 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7220 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7221 * and everything else from the nested clause.
7224 for (i = 0; i < ei_len; ++i) {
7225 gint32 cindex1 = *(gint32*)type_info [i];
7226 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7228 for (j = 0; j < cfg->header->num_clauses; ++j) {
7230 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7231 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7233 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7234 /* clause1 is the nested clause */
7235 nested_ei = &cfg->llvm_ex_info [i];
7236 nesting_ei = &cfg->llvm_ex_info [nindex];
7239 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7241 nesting_ei->flags = clause2->flags;
7242 nesting_ei->data.catch_class = clause2->data.catch_class;
7243 nesting_ei->clause_index = cindex2;
7247 g_assert (nindex == ei_len + nested_len);
7248 cfg->llvm_this_reg = this_reg;
7249 cfg->llvm_this_offset = this_offset;
7251 /* type_info [i] is cfg mempool allocated, no need to free it */
7258 dlsym_cb (const char *name, void **symbol)
7264 if (!strcmp (name, "__bzero")) {
7265 *symbol = (void*)bzero;
7267 current = mono_dl_open (NULL, 0, NULL);
7270 err = mono_dl_symbol (current, name, symbol);
7272 mono_dl_close (current);
7274 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7275 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7281 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7283 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7287 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7289 LLVMTypeRef param_types [4];
7291 param_types [0] = param_type1;
7292 param_types [1] = param_type2;
7294 AddFunc (module, name, ret_type, param_types, 2);
7298 add_intrinsics (LLVMModuleRef module)
7300 /* Emit declarations of instrinsics */
7302 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7303 * type doesn't seem to do any locking.
7306 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7308 memset_param_count = 5;
7309 memset_func_name = "llvm.memset.p0i8.i32";
7311 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7315 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7317 memcpy_param_count = 5;
7318 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7320 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7324 LLVMTypeRef params [] = { LLVMDoubleType () };
7326 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7327 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7328 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7330 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7331 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7335 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7336 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7337 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7339 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7340 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7341 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7342 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7343 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7344 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7345 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7349 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7350 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7351 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7353 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7354 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7355 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7356 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7357 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7358 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7361 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7362 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7366 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7368 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7371 /* SSE intrinsics */
7372 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7374 LLVMTypeRef ret_type, arg_types [16];
7377 ret_type = type_to_simd_type (MONO_TYPE_I4);
7378 arg_types [0] = ret_type;
7379 arg_types [1] = ret_type;
7380 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7383 ret_type = type_to_simd_type (MONO_TYPE_I2);
7384 arg_types [0] = ret_type;
7385 arg_types [1] = ret_type;
7386 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7387 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7388 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7389 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7390 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7391 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7392 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7394 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7395 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7397 ret_type = type_to_simd_type (MONO_TYPE_I1);
7398 arg_types [0] = ret_type;
7399 arg_types [1] = ret_type;
7400 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7401 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7402 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7403 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7404 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7405 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7406 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7408 ret_type = type_to_simd_type (MONO_TYPE_R8);
7409 arg_types [0] = ret_type;
7410 arg_types [1] = ret_type;
7411 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7412 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7413 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7414 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7415 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7417 ret_type = type_to_simd_type (MONO_TYPE_R4);
7418 arg_types [0] = ret_type;
7419 arg_types [1] = ret_type;
7420 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7421 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7422 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7423 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7424 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7427 ret_type = type_to_simd_type (MONO_TYPE_I1);
7428 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7429 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7430 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7431 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7432 ret_type = type_to_simd_type (MONO_TYPE_I2);
7433 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7434 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7435 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7436 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7439 ret_type = type_to_simd_type (MONO_TYPE_R8);
7440 arg_types [0] = ret_type;
7441 arg_types [1] = ret_type;
7442 arg_types [2] = LLVMInt8Type ();
7443 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7444 ret_type = type_to_simd_type (MONO_TYPE_R4);
7445 arg_types [0] = ret_type;
7446 arg_types [1] = ret_type;
7447 arg_types [2] = LLVMInt8Type ();
7448 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7450 /* Conversion ops */
7451 ret_type = type_to_simd_type (MONO_TYPE_R8);
7452 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7453 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7454 ret_type = type_to_simd_type (MONO_TYPE_R4);
7455 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7456 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7457 ret_type = type_to_simd_type (MONO_TYPE_I4);
7458 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7459 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7460 ret_type = type_to_simd_type (MONO_TYPE_I4);
7461 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7462 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7463 ret_type = type_to_simd_type (MONO_TYPE_R4);
7464 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7465 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7466 ret_type = type_to_simd_type (MONO_TYPE_R8);
7467 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7468 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7470 ret_type = type_to_simd_type (MONO_TYPE_I4);
7471 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7472 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7473 ret_type = type_to_simd_type (MONO_TYPE_I4);
7474 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7475 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7478 ret_type = type_to_simd_type (MONO_TYPE_R8);
7479 arg_types [0] = ret_type;
7480 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7481 ret_type = type_to_simd_type (MONO_TYPE_R4);
7482 arg_types [0] = ret_type;
7483 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7484 ret_type = type_to_simd_type (MONO_TYPE_R4);
7485 arg_types [0] = ret_type;
7486 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7487 ret_type = type_to_simd_type (MONO_TYPE_R4);
7488 arg_types [0] = ret_type;
7489 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7492 ret_type = type_to_simd_type (MONO_TYPE_I2);
7493 arg_types [0] = ret_type;
7494 arg_types [1] = LLVMInt32Type ();
7495 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7496 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7497 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7498 ret_type = type_to_simd_type (MONO_TYPE_I4);
7499 arg_types [0] = ret_type;
7500 arg_types [1] = LLVMInt32Type ();
7501 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7502 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7503 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7504 ret_type = type_to_simd_type (MONO_TYPE_I8);
7505 arg_types [0] = ret_type;
7506 arg_types [1] = LLVMInt32Type ();
7507 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7508 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7511 ret_type = LLVMInt32Type ();
7512 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7513 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7516 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7519 /* Load/Store intrinsics */
7521 LLVMTypeRef arg_types [5];
7525 for (i = 1; i <= 8; i *= 2) {
7526 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7527 arg_types [1] = LLVMInt32Type ();
7528 arg_types [2] = LLVMInt1Type ();
7529 arg_types [3] = LLVMInt32Type ();
7530 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7531 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7533 arg_types [0] = LLVMIntType (i * 8);
7534 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7535 arg_types [2] = LLVMInt32Type ();
7536 arg_types [3] = LLVMInt1Type ();
7537 arg_types [4] = LLVMInt32Type ();
7538 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7539 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7545 add_types (MonoLLVMModule *module)
7547 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7551 mono_llvm_init (void)
7553 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7557 init_jit_module (MonoDomain *domain)
7559 MonoJitICallInfo *info;
7560 MonoJitDomainInfo *dinfo;
7561 MonoLLVMModule *module;
7564 dinfo = domain_jit_info (domain);
7565 if (dinfo->llvm_module)
7568 mono_loader_lock ();
7570 if (dinfo->llvm_module) {
7571 mono_loader_unlock ();
7575 module = g_new0 (MonoLLVMModule, 1);
7577 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7578 module->lmodule = LLVMModuleCreateWithName (name);
7579 module->context = LLVMGetGlobalContext ();
7581 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7583 add_intrinsics (module->lmodule);
7586 module->llvm_types = g_hash_table_new (NULL, NULL);
7588 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7590 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7592 mono_memory_barrier ();
7594 dinfo->llvm_module = module;
7596 mono_loader_unlock ();
7600 mono_llvm_cleanup (void)
7602 MonoLLVMModule *module = &aot_module;
7604 if (module->lmodule)
7605 LLVMDisposeModule (module->lmodule);
7607 if (module->context)
7608 LLVMContextDispose (module->context);
7612 mono_llvm_free_domain_info (MonoDomain *domain)
7614 MonoJitDomainInfo *info = domain_jit_info (domain);
7615 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7621 if (module->llvm_types)
7622 g_hash_table_destroy (module->llvm_types);
7624 mono_llvm_dispose_ee (module->mono_ee);
7626 if (module->bb_names) {
7627 for (i = 0; i < module->bb_names_len; ++i)
7628 g_free (module->bb_names [i]);
7629 g_free (module->bb_names);
7631 //LLVMDisposeModule (module->module);
7635 info->llvm_module = NULL;
7639 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7641 MonoLLVMModule *module = &aot_module;
7643 /* Delete previous module */
7644 if (module->plt_entries)
7645 g_hash_table_destroy (module->plt_entries);
7646 if (module->lmodule)
7647 LLVMDisposeModule (module->lmodule);
7649 memset (module, 0, sizeof (aot_module));
7651 module->lmodule = LLVMModuleCreateWithName ("aot");
7652 module->assembly = assembly;
7653 module->global_prefix = g_strdup (global_prefix);
7654 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7655 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7656 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7657 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7658 module->external_symbols = TRUE;
7659 module->emit_dwarf = emit_dwarf;
7660 module->static_link = static_link;
7661 module->llvm_only = llvm_only;
7662 /* The first few entries are reserved */
7663 module->max_got_offset = 16;
7664 module->context = LLVMContextCreate ();
7667 /* clang ignores our debug info because it has an invalid version */
7668 module->emit_dwarf = FALSE;
7670 add_intrinsics (module->lmodule);
7675 * We couldn't compute the type of the LLVM global representing the got because
7676 * its size is only known after all the methods have been emitted. So create
7677 * a dummy variable, and replace all uses it with the real got variable when
7678 * its size is known in mono_llvm_emit_aot_module ().
7681 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7683 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7684 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7687 /* Add initialization array */
7689 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7691 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7692 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7696 emit_init_icall_wrappers (module);
7698 emit_llvm_code_start (module);
7700 /* Add a dummy personality function */
7701 if (!use_debug_personality) {
7702 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7703 LLVMSetLinkage (personality, LLVMExternalLinkage);
7704 mark_as_used (module, personality);
7707 /* Add a reference to the c++ exception we throw/catch */
7709 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7710 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7711 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7712 mono_llvm_set_is_constant (module->sentinel_exception);
7715 module->llvm_types = g_hash_table_new (NULL, NULL);
7716 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7717 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7718 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7719 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7720 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7721 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7722 module->method_to_callers = g_hash_table_new (NULL, NULL);
7726 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7729 LLVMValueRef res, *vals;
7731 vals = g_new0 (LLVMValueRef, nvalues);
7732 for (i = 0; i < nvalues; ++i)
7733 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7734 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7740 * mono_llvm_emit_aot_file_info:
7742 * Emit the MonoAotFileInfo structure.
7743 * Same as emit_aot_file_info () in aot-compiler.c.
7746 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7748 MonoLLVMModule *module = &aot_module;
7750 /* Save these for later */
7751 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7752 module->has_jitted_code = has_jitted_code;
7756 * mono_llvm_emit_aot_data:
7758 * Emit the binary data DATA pointed to by symbol SYMBOL.
7761 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7763 MonoLLVMModule *module = &aot_module;
7767 type = LLVMArrayType (LLVMInt8Type (), data_len);
7768 d = LLVMAddGlobal (module->lmodule, type, symbol);
7769 LLVMSetVisibility (d, LLVMHiddenVisibility);
7770 LLVMSetLinkage (d, LLVMInternalLinkage);
7771 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7772 mono_llvm_set_is_constant (d);
7775 /* Add a reference to a global defined in JITted code */
7777 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7782 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7783 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7789 emit_aot_file_info (MonoLLVMModule *module)
7791 LLVMTypeRef file_info_type;
7792 LLVMTypeRef *eltypes, eltype;
7793 LLVMValueRef info_var;
7794 LLVMValueRef *fields;
7795 int i, nfields, tindex;
7796 MonoAotFileInfo *info;
7797 LLVMModuleRef lmodule = module->lmodule;
7799 info = &module->aot_info;
7801 /* Create an LLVM type to represent MonoAotFileInfo */
7802 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7803 eltypes = g_new (LLVMTypeRef, nfields);
7805 eltypes [tindex ++] = LLVMInt32Type ();
7806 eltypes [tindex ++] = LLVMInt32Type ();
7808 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7809 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7811 for (i = 0; i < 15; ++i)
7812 eltypes [tindex ++] = LLVMInt32Type ();
7814 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7815 for (i = 0; i < 4; ++i)
7816 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7817 g_assert (tindex == nfields);
7818 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7819 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7821 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7822 if (module->static_link) {
7823 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7824 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7826 fields = g_new (LLVMValueRef, nfields);
7828 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7829 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7833 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7834 * for symbols defined in the .s file emitted by the aot compiler.
7836 eltype = eltypes [tindex];
7837 if (module->llvm_only)
7838 fields [tindex ++] = LLVMConstNull (eltype);
7840 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7841 fields [tindex ++] = module->got_var;
7842 /* llc defines this directly */
7843 if (!module->llvm_only) {
7844 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7845 fields [tindex ++] = LLVMConstNull (eltype);
7846 fields [tindex ++] = LLVMConstNull (eltype);
7848 fields [tindex ++] = LLVMConstNull (eltype);
7849 fields [tindex ++] = module->get_method;
7850 fields [tindex ++] = module->get_unbox_tramp;
7852 if (module->has_jitted_code) {
7853 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7854 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7856 fields [tindex ++] = LLVMConstNull (eltype);
7857 fields [tindex ++] = LLVMConstNull (eltype);
7859 if (!module->llvm_only)
7860 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7862 fields [tindex ++] = LLVMConstNull (eltype);
7863 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7864 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7865 fields [tindex ++] = LLVMConstNull (eltype);
7867 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7868 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7869 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7870 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7871 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7872 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7873 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7874 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7875 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7876 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7878 /* Not needed (mem_end) */
7879 fields [tindex ++] = LLVMConstNull (eltype);
7880 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7881 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7882 if (info->trampoline_size [0]) {
7883 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7884 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7885 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7886 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7888 fields [tindex ++] = LLVMConstNull (eltype);
7889 fields [tindex ++] = LLVMConstNull (eltype);
7890 fields [tindex ++] = LLVMConstNull (eltype);
7891 fields [tindex ++] = LLVMConstNull (eltype);
7893 if (module->static_link && !module->llvm_only)
7894 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7896 fields [tindex ++] = LLVMConstNull (eltype);
7897 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7898 if (!module->llvm_only) {
7899 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7900 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7901 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7902 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7903 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7904 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7906 fields [tindex ++] = LLVMConstNull (eltype);
7907 fields [tindex ++] = LLVMConstNull (eltype);
7908 fields [tindex ++] = LLVMConstNull (eltype);
7909 fields [tindex ++] = LLVMConstNull (eltype);
7910 fields [tindex ++] = LLVMConstNull (eltype);
7911 fields [tindex ++] = LLVMConstNull (eltype);
7914 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7915 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7918 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7919 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7920 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7921 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7922 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7923 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7924 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7925 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7926 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7927 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7928 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7929 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7930 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7931 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7932 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7934 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7935 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7936 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7937 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7938 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7939 g_assert (tindex == nfields);
7941 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7943 if (module->static_link) {
7947 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7948 /* Get rid of characters which cannot occur in symbols */
7950 for (p = s; *p; ++p) {
7951 if (!(isalnum (*p) || *p == '_'))
7954 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7956 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7957 LLVMSetLinkage (var, LLVMExternalLinkage);
7962 * Emit the aot module into the LLVM bitcode file FILENAME.
7965 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7967 LLVMTypeRef got_type, inited_type;
7968 LLVMValueRef real_got, real_inited;
7969 MonoLLVMModule *module = &aot_module;
7971 emit_llvm_code_end (module);
7974 * Create the real got variable and replace all uses of the dummy variable with
7977 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7978 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7979 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7980 if (module->external_symbols) {
7981 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7982 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7984 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7986 mono_llvm_replace_uses_of (module->got_var, real_got);
7988 mark_as_used (&aot_module, real_got);
7990 /* Delete the dummy got so it doesn't become a global */
7991 LLVMDeleteGlobal (module->got_var);
7992 module->got_var = real_got;
7995 * Same for the init_var
7997 if (module->llvm_only) {
7998 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7999 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8000 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8001 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8002 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8003 LLVMDeleteGlobal (module->inited_var);
8006 if (module->llvm_only) {
8007 emit_get_method (&aot_module);
8008 emit_get_unbox_tramp (&aot_module);
8011 emit_llvm_used (&aot_module);
8012 emit_dbg_info (&aot_module, filename, cu_name);
8013 emit_aot_file_info (&aot_module);
8016 * Replace GOT entries for directly callable methods with the methods themselves.
8017 * It would be easier to implement this by predefining all methods before compiling
8018 * their bodies, but that couldn't handle the case when a method fails to compile
8021 if (module->llvm_only) {
8022 GHashTableIter iter;
8024 GSList *callers, *l;
8026 g_hash_table_iter_init (&iter, module->method_to_callers);
8027 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8028 LLVMValueRef lmethod;
8030 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8032 for (l = callers; l; l = l->next) {
8033 LLVMValueRef caller = (LLVMValueRef)l->data;
8035 mono_llvm_replace_uses_of (caller, lmethod);
8041 /* Replace PLT entries for directly callable methods with the methods themselves */
8043 GHashTableIter iter;
8045 LLVMValueRef callee;
8047 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8048 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8049 if (mono_aot_is_direct_callable (ji)) {
8050 LLVMValueRef lmethod;
8052 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8053 /* The types might not match because the caller might pass an rgctx */
8054 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8055 mono_llvm_replace_uses_of (callee, lmethod);
8056 mono_aot_mark_unused_llvm_plt_entry (ji);
8066 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
8067 g_assert_not_reached ();
8072 LLVMWriteBitcodeToFile (module->lmodule, filename);
8077 md_string (const char *s)
8079 return LLVMMDString (s, strlen (s));
8082 /* Debugging support */
8085 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8087 LLVMModuleRef lmodule = module->lmodule;
8088 LLVMValueRef args [16], cu_args [16], cu, ver;
8090 char *build_info, *s, *dir;
8093 * This can only be enabled when LLVM code is emitted into a separate object
8094 * file, since the AOT compiler also emits dwarf info,
8095 * and the abbrev indexes will not be correct since llvm has added its own
8098 if (!module->emit_dwarf)
8102 * Emit dwarf info in the form of LLVM metadata. There is some
8103 * out-of-date documentation at:
8104 * http://llvm.org/docs/SourceLevelDebugging.html
8105 * but most of this was gathered from the llvm and
8110 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8111 /* CU name/compilation dir */
8112 dir = g_path_get_dirname (filename);
8113 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8114 args [1] = LLVMMDString (dir, strlen (dir));
8115 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8118 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8120 build_info = mono_get_runtime_build_info ();
8121 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8122 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8123 g_free (build_info);
8125 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8127 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8128 /* Runtime version */
8129 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8131 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8132 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8134 if (module->subprogram_mds) {
8138 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8139 for (i = 0; i < module->subprogram_mds->len; ++i)
8140 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8141 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8143 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8146 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8147 /* Imported modules */
8148 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8150 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8151 /* DebugEmissionKind = FullDebug */
8152 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8153 cu = LLVMMDNode (cu_args, n_cuargs);
8154 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8156 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8157 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8158 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8159 ver = LLVMMDNode (args, 3);
8160 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8162 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8163 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8164 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8165 ver = LLVMMDNode (args, 3);
8166 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8170 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8172 MonoLLVMModule *module = ctx->module;
8173 MonoDebugMethodInfo *minfo = ctx->minfo;
8174 char *source_file, *dir, *filename;
8175 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8176 MonoSymSeqPoint *sym_seq_points;
8182 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8184 source_file = g_strdup ("<unknown>");
8185 dir = g_path_get_dirname (source_file);
8186 filename = g_path_get_basename (source_file);
8188 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8189 args [0] = md_string (filename);
8190 args [1] = md_string (dir);
8191 ctx_args [1] = LLVMMDNode (args, 2);
8192 ctx_md = LLVMMDNode (ctx_args, 2);
8194 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8195 type_args [1] = NULL;
8196 type_args [2] = NULL;
8197 type_args [3] = LLVMMDString ("", 0);
8198 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8199 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8200 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8201 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8202 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8203 type_args [9] = NULL;
8204 type_args [10] = NULL;
8205 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8206 type_args [12] = NULL;
8207 type_args [13] = NULL;
8208 type_args [14] = NULL;
8209 type_md = LLVMMDNode (type_args, 14);
8211 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8212 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8213 /* Source directory + file pair */
8214 args [0] = md_string (filename);
8215 args [1] = md_string (dir);
8216 md_args [1] = LLVMMDNode (args ,2);
8217 md_args [2] = ctx_md;
8218 md_args [3] = md_string (cfg->method->name);
8219 md_args [4] = md_string (name);
8220 md_args [5] = md_string (name);
8223 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8225 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8227 md_args [7] = type_md;
8229 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8231 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8233 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8234 /* Index into a virtual function */
8235 md_args [11] = NULL;
8236 md_args [12] = NULL;
8238 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8240 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8241 /* Pointer to LLVM function */
8242 md_args [15] = method;
8243 /* Function template parameter */
8244 md_args [16] = NULL;
8245 /* Function declaration descriptor */
8246 md_args [17] = NULL;
8247 /* List of function variables */
8248 md_args [18] = LLVMMDNode (args, 0);
8250 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8251 md = LLVMMDNode (md_args, 20);
8253 if (!module->subprogram_mds)
8254 module->subprogram_mds = g_ptr_array_new ();
8255 g_ptr_array_add (module->subprogram_mds, md);
8259 g_free (source_file);
8260 g_free (sym_seq_points);
8266 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8268 MonoCompile *cfg = ctx->cfg;
8270 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8271 MonoDebugSourceLocation *loc;
8272 LLVMValueRef loc_md, md_args [16];
8275 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8279 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8280 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8281 md_args [nmd_args ++] = ctx->dbg_md;
8282 md_args [nmd_args ++] = NULL;
8283 loc_md = LLVMMDNode (md_args, nmd_args);
8284 LLVMSetCurrentDebugLocation (builder, loc_md);
8285 mono_debug_symfile_free_location (loc);
8291 default_mono_llvm_unhandled_exception (void)
8293 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8294 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8296 mono_unhandled_exception (target);
8297 exit (mono_environment_exitcode_get ());
8302 - Emit LLVM IR from the mono IR using the LLVM C API.
8303 - The original arch specific code remains, so we can fall back to it if we run
8304 into something we can't handle.
8308 A partial list of issues:
8309 - Handling of opcodes which can throw exceptions.
8311 In the mono JIT, these are implemented using code like this:
8318 push throw_pos - method
8319 call <exception trampoline>
8321 The problematic part is push throw_pos - method, which cannot be represented
8322 in the LLVM IR, since it does not support label values.
8323 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8324 be implemented in JIT mode ?
8325 -> a possible but slower implementation would use the normal exception
8326 throwing code but it would need to control the placement of the throw code
8327 (it needs to be exactly after the compare+branch).
8328 -> perhaps add a PC offset intrinsics ?
8330 - efficient implementation of .ovf opcodes.
8332 These are currently implemented as:
8333 <ins which sets the condition codes>
8336 Some overflow opcodes are now supported by LLVM SVN.
8338 - exception handling, unwinding.
8339 - SSA is disabled for methods with exception handlers
8340 - How to obtain unwind info for LLVM compiled methods ?
8341 -> this is now solved by converting the unwind info generated by LLVM
8343 - LLVM uses the c++ exception handling framework, while we use our home grown
8344 code, and couldn't use the c++ one:
8345 - its not supported under VC++, other exotic platforms.
8346 - it might be impossible to support filter clauses with it.
8350 The trampolines need a predictable call sequence, since they need to disasm
8351 the calling code to obtain register numbers / offsets.
8353 LLVM currently generates this code in non-JIT mode:
8354 mov -0x98(%rax),%eax
8356 Here, the vtable pointer is lost.
8357 -> solution: use one vtable trampoline per class.
8359 - passing/receiving the IMT pointer/RGCTX.
8360 -> solution: pass them as normal arguments ?
8364 LLVM does not allow the specification of argument registers etc. This means
8365 that all calls are made according to the platform ABI.
8367 - passing/receiving vtypes.
8369 Vtypes passed/received in registers are handled by the front end by using
8370 a signature with scalar arguments, and loading the parts of the vtype into those
8373 Vtypes passed on the stack are handled using the 'byval' attribute.
8377 Supported though alloca, we need to emit the load/store code.
8381 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8382 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8383 This is made easier because the IR is already in SSA form.
8384 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8385 types are frequently used incorrectly.
8390 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8391 it with the file containing the methods emitted by the JIT and the AOT data
8395 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8396 * - each bblock should end with a branch
8397 * - setting the return value, making cfg->ret non-volatile
8398 * - avoid some transformations in the JIT which make it harder for us to generate
8400 * - use pointer types to help optimizations.