2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
49 * Information associated by mono with LLVM modules.
52 LLVMModuleRef lmodule;
53 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
54 GHashTable *llvm_types;
56 const char *got_symbol;
57 const char *get_method_symbol;
58 const char *get_unbox_tramp_symbol;
59 GHashTable *plt_entries;
60 GHashTable *plt_entries_ji;
61 GHashTable *method_to_lmethod;
62 GHashTable *direct_callables;
67 GPtrArray *subprogram_mds;
69 LLVMExecutionEngineRef ee;
70 gboolean external_symbols;
75 MonoAssembly *assembly;
77 MonoAotFileInfo aot_info;
78 const char *jit_got_symbol;
79 const char *eh_frame_symbol;
80 LLVMValueRef get_method, get_unbox_tramp;
81 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
82 LLVMValueRef code_start, code_end;
83 LLVMValueRef inited_var;
84 int max_inited_idx, max_method_idx;
85 gboolean has_jitted_code;
88 GHashTable *idx_to_lmethod;
89 GHashTable *idx_to_unbox_tramp;
90 /* Maps a MonoMethod to LLVM instructions representing it */
91 GHashTable *method_to_callers;
92 LLVMContextRef context;
93 LLVMValueRef sentinel_exception;
97 * Information associated by the backend with mono basic blocks.
100 LLVMBasicBlockRef bblock, end_bblock;
101 LLVMValueRef finally_ind;
102 gboolean added, invoke_target;
104 * If this bblock is the start of a finally clause, this is a list of bblocks it
105 * needs to branch to in ENDFINALLY.
107 GSList *call_handler_return_bbs;
109 * If this bblock is the start of a finally clause, this is the bblock that
110 * CALL_HANDLER needs to branch to.
112 LLVMBasicBlockRef call_handler_target_bb;
113 /* The list of switch statements generated by ENDFINALLY instructions */
114 GSList *endfinally_switch_ins_list;
119 * Structure containing emit state
122 MonoMemPool *mempool;
124 /* Maps method names to the corresponding LLVMValueRef */
125 GHashTable *emitted_method_decls;
128 LLVMValueRef lmethod;
129 MonoLLVMModule *module;
130 LLVMModuleRef lmodule;
132 int sindex, default_index, ex_index;
133 LLVMBuilderRef builder;
134 LLVMValueRef *values, *addresses;
135 MonoType **vreg_cli_types;
137 MonoMethodSignature *sig;
139 GHashTable *region_to_handler;
140 GHashTable *clause_to_handler;
141 LLVMBuilderRef alloca_builder;
142 LLVMValueRef last_alloca;
143 LLVMValueRef rgctx_arg;
144 LLVMValueRef this_arg;
145 LLVMTypeRef *vreg_types;
146 LLVMTypeRef method_type;
147 LLVMBasicBlockRef init_bb, inited_bb;
149 gboolean *unreachable;
151 gboolean has_got_access;
152 gboolean is_linkonce;
153 int this_arg_pindex, rgctx_arg_pindex;
154 LLVMValueRef imt_rgctx_loc;
155 GHashTable *llvm_types;
157 MonoDebugMethodInfo *minfo;
159 /* For every clause, the clauses it is nested in */
162 GHashTable *exc_meta;
163 GHashTable *method_to_callers;
164 GPtrArray *phi_values;
165 GPtrArray *bblock_list;
172 MonoBasicBlock *in_bb;
177 * Instruction metadata
178 * This is the same as ins_info, but LREG != IREG.
186 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
187 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
194 /* keep in sync with the enum in mini.h */
197 #include "mini-ops.h"
202 #if SIZEOF_VOID_P == 4
203 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
205 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
208 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
211 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
213 #define TRACE_FAILURE(msg)
217 #define IS_TARGET_X86 1
219 #define IS_TARGET_X86 0
223 #define IS_TARGET_AMD64 1
225 #define IS_TARGET_AMD64 0
228 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
230 static LLVMIntPredicate cond_to_llvm_cond [] = {
243 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
256 static MonoNativeTlsKey current_cfg_tls_id;
258 static MonoLLVMModule aot_module;
259 static int memset_param_count, memcpy_param_count;
260 static const char *memset_func_name;
261 static const char *memcpy_func_name;
263 static void init_jit_module (MonoDomain *domain);
265 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
266 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
267 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
271 set_failure (EmitContext *ctx, const char *message)
273 TRACE_FAILURE (reason);
274 ctx->cfg->exception_message = g_strdup (message);
275 ctx->cfg->disable_llvm = TRUE;
281 * The LLVM type with width == sizeof (gpointer)
286 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
292 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 * Return the size of the LLVM representation of the vtype T.
307 get_vtype_size (MonoType *t)
311 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
313 /* LLVMArgAsIArgs depends on this since it stores whole words */
314 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
321 * simd_class_to_llvm_type:
323 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
326 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
328 if (!strcmp (klass->name, "Vector2d")) {
329 return LLVMVectorType (LLVMDoubleType (), 2);
330 } else if (!strcmp (klass->name, "Vector2l")) {
331 return LLVMVectorType (LLVMInt64Type (), 2);
332 } else if (!strcmp (klass->name, "Vector2ul")) {
333 return LLVMVectorType (LLVMInt64Type (), 2);
334 } else if (!strcmp (klass->name, "Vector4i")) {
335 return LLVMVectorType (LLVMInt32Type (), 4);
336 } else if (!strcmp (klass->name, "Vector4ui")) {
337 return LLVMVectorType (LLVMInt32Type (), 4);
338 } else if (!strcmp (klass->name, "Vector4f")) {
339 return LLVMVectorType (LLVMFloatType (), 4);
340 } else if (!strcmp (klass->name, "Vector8s")) {
341 return LLVMVectorType (LLVMInt16Type (), 8);
342 } else if (!strcmp (klass->name, "Vector8us")) {
343 return LLVMVectorType (LLVMInt16Type (), 8);
344 } else if (!strcmp (klass->name, "Vector16sb")) {
345 return LLVMVectorType (LLVMInt8Type (), 16);
346 } else if (!strcmp (klass->name, "Vector16b")) {
347 return LLVMVectorType (LLVMInt8Type (), 16);
349 printf ("%s\n", klass->name);
355 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
356 static inline G_GNUC_UNUSED LLVMTypeRef
357 type_to_simd_type (int type)
361 return LLVMVectorType (LLVMInt8Type (), 16);
363 return LLVMVectorType (LLVMInt16Type (), 8);
365 return LLVMVectorType (LLVMInt32Type (), 4);
367 return LLVMVectorType (LLVMInt64Type (), 2);
369 return LLVMVectorType (LLVMDoubleType (), 2);
371 return LLVMVectorType (LLVMFloatType (), 4);
373 g_assert_not_reached ();
379 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
381 int i, size, nfields, esize;
382 LLVMTypeRef *eltypes;
387 t = &klass->byval_arg;
389 if (mini_type_is_hfa (t, &nfields, &esize)) {
391 * This is needed on arm64 where HFAs are returned in
395 eltypes = g_new (LLVMTypeRef, size);
396 for (i = 0; i < size; ++i)
397 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
399 size = get_vtype_size (t);
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = LLVMInt8Type ();
406 name = mono_type_full_name (&klass->byval_arg);
407 ltype = LLVMStructCreateNamed (module->context, name);
408 LLVMStructSetBody (ltype, eltypes, size, FALSE);
418 * Return the LLVM type corresponding to T.
421 type_to_llvm_type (EmitContext *ctx, MonoType *t)
423 t = mini_get_underlying_type (t);
427 return LLVMVoidType ();
429 return LLVMInt8Type ();
431 return LLVMInt16Type ();
433 return LLVMInt32Type ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
440 case MONO_TYPE_BOOLEAN:
441 return LLVMInt8Type ();
444 return LLVMInt64Type ();
446 return LLVMInt16Type ();
448 return LLVMFloatType ();
450 return LLVMDoubleType ();
453 return IntPtrType ();
454 case MONO_TYPE_OBJECT:
455 case MONO_TYPE_CLASS:
456 case MONO_TYPE_ARRAY:
457 case MONO_TYPE_SZARRAY:
458 case MONO_TYPE_STRING:
460 return ObjRefType ();
463 /* Because of generic sharing */
464 return ObjRefType ();
465 case MONO_TYPE_GENERICINST:
466 if (!mono_type_generic_inst_is_valuetype (t))
467 return ObjRefType ();
469 case MONO_TYPE_VALUETYPE:
470 case MONO_TYPE_TYPEDBYREF: {
474 klass = mono_class_from_mono_type (t);
476 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
477 return simd_class_to_llvm_type (ctx, klass);
480 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
482 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
484 ltype = create_llvm_type_for_type (ctx->module, klass);
485 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
491 printf ("X: %d\n", t->type);
492 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
493 ctx->cfg->disable_llvm = TRUE;
501 * Return whenever T is an unsigned int type.
504 type_is_unsigned (EmitContext *ctx, MonoType *t)
506 t = mini_get_underlying_type (t);
522 * type_to_llvm_arg_type:
524 * Same as type_to_llvm_type, but treat i8/i16 as i32.
527 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
529 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
531 if (ctx->cfg->llvm_only)
535 * This works on all abis except arm64/ios which passes multiple
536 * arguments in one stack slot.
539 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
541 * LLVM generates code which only sets the lower bits, while JITted
542 * code expects all the bits to be set.
544 ptype = LLVMInt32Type ();
552 * llvm_type_to_stack_type:
554 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
557 static G_GNUC_UNUSED LLVMTypeRef
558 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
562 if (type == LLVMInt8Type ())
563 return LLVMInt32Type ();
564 else if (type == LLVMInt16Type ())
565 return LLVMInt32Type ();
566 else if (!cfg->r4fp && type == LLVMFloatType ())
567 return LLVMDoubleType ();
573 * regtype_to_llvm_type:
575 * Return the LLVM type corresponding to the regtype C used in instruction
579 regtype_to_llvm_type (char c)
583 return LLVMInt32Type ();
585 return LLVMInt64Type ();
587 return LLVMDoubleType ();
596 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
599 op_to_llvm_type (int opcode)
604 return LLVMInt8Type ();
607 return LLVMInt8Type ();
610 return LLVMInt16Type ();
613 return LLVMInt16Type ();
616 return LLVMInt32Type ();
619 return LLVMInt32Type ();
621 return LLVMInt64Type ();
623 return LLVMFloatType ();
625 return LLVMDoubleType ();
627 return LLVMInt64Type ();
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
636 return LLVMInt8Type ();
641 return LLVMInt16Type ();
643 return LLVMInt32Type ();
646 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
653 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 printf ("%s\n", mono_inst_name (opcode));
663 g_assert_not_reached ();
668 #define CLAUSE_START(clause) ((clause)->try_offset)
669 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
672 * load_store_to_llvm_type:
674 * Return the size/sign/zero extension corresponding to the load/store opcode
678 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
684 case OP_LOADI1_MEMBASE:
685 case OP_STOREI1_MEMBASE_REG:
686 case OP_STOREI1_MEMBASE_IMM:
687 case OP_ATOMIC_LOAD_I1:
688 case OP_ATOMIC_STORE_I1:
691 return LLVMInt8Type ();
692 case OP_LOADU1_MEMBASE:
694 case OP_ATOMIC_LOAD_U1:
695 case OP_ATOMIC_STORE_U1:
698 return LLVMInt8Type ();
699 case OP_LOADI2_MEMBASE:
700 case OP_STOREI2_MEMBASE_REG:
701 case OP_STOREI2_MEMBASE_IMM:
702 case OP_ATOMIC_LOAD_I2:
703 case OP_ATOMIC_STORE_I2:
706 return LLVMInt16Type ();
707 case OP_LOADU2_MEMBASE:
709 case OP_ATOMIC_LOAD_U2:
710 case OP_ATOMIC_STORE_U2:
713 return LLVMInt16Type ();
714 case OP_LOADI4_MEMBASE:
715 case OP_LOADU4_MEMBASE:
718 case OP_STOREI4_MEMBASE_REG:
719 case OP_STOREI4_MEMBASE_IMM:
720 case OP_ATOMIC_LOAD_I4:
721 case OP_ATOMIC_STORE_I4:
722 case OP_ATOMIC_LOAD_U4:
723 case OP_ATOMIC_STORE_U4:
725 return LLVMInt32Type ();
726 case OP_LOADI8_MEMBASE:
728 case OP_STOREI8_MEMBASE_REG:
729 case OP_STOREI8_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I8:
731 case OP_ATOMIC_STORE_I8:
732 case OP_ATOMIC_LOAD_U8:
733 case OP_ATOMIC_STORE_U8:
735 return LLVMInt64Type ();
736 case OP_LOADR4_MEMBASE:
737 case OP_STORER4_MEMBASE_REG:
738 case OP_ATOMIC_LOAD_R4:
739 case OP_ATOMIC_STORE_R4:
741 return LLVMFloatType ();
742 case OP_LOADR8_MEMBASE:
743 case OP_STORER8_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R8:
745 case OP_ATOMIC_STORE_R8:
747 return LLVMDoubleType ();
748 case OP_LOAD_MEMBASE:
750 case OP_STORE_MEMBASE_REG:
751 case OP_STORE_MEMBASE_IMM:
752 *size = sizeof (gpointer);
753 return IntPtrType ();
755 g_assert_not_reached ();
763 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
766 ovf_op_to_intrins (int opcode)
770 return "llvm.sadd.with.overflow.i32";
772 return "llvm.uadd.with.overflow.i32";
774 return "llvm.ssub.with.overflow.i32";
776 return "llvm.usub.with.overflow.i32";
778 return "llvm.smul.with.overflow.i32";
780 return "llvm.umul.with.overflow.i32";
782 return "llvm.sadd.with.overflow.i64";
784 return "llvm.uadd.with.overflow.i64";
786 return "llvm.ssub.with.overflow.i64";
788 return "llvm.usub.with.overflow.i64";
790 return "llvm.smul.with.overflow.i64";
792 return "llvm.umul.with.overflow.i64";
794 g_assert_not_reached ();
800 simd_op_to_intrins (int opcode)
803 #if defined(TARGET_X86) || defined(TARGET_AMD64)
805 return "llvm.x86.sse2.min.pd";
807 return "llvm.x86.sse.min.ps";
809 return "llvm.x86.sse41.pminud";
811 return "llvm.x86.sse41.pminuw";
813 return "llvm.x86.sse2.pminu.b";
815 return "llvm.x86.sse2.pmins.w";
817 return "llvm.x86.sse2.max.pd";
819 return "llvm.x86.sse.max.ps";
821 return "llvm.x86.sse3.hadd.pd";
823 return "llvm.x86.sse3.hadd.ps";
825 return "llvm.x86.sse3.hsub.pd";
827 return "llvm.x86.sse3.hsub.ps";
829 return "llvm.x86.sse41.pmaxud";
831 return "llvm.x86.sse41.pmaxuw";
833 return "llvm.x86.sse2.pmaxu.b";
835 return "llvm.x86.sse3.addsub.ps";
837 return "llvm.x86.sse3.addsub.pd";
838 case OP_EXTRACT_MASK:
839 return "llvm.x86.sse2.pmovmskb.128";
842 return "llvm.x86.sse2.psrli.w";
845 return "llvm.x86.sse2.psrli.d";
848 return "llvm.x86.sse2.psrli.q";
851 return "llvm.x86.sse2.pslli.w";
854 return "llvm.x86.sse2.pslli.d";
857 return "llvm.x86.sse2.pslli.q";
860 return "llvm.x86.sse2.psrai.w";
863 return "llvm.x86.sse2.psrai.d";
865 return "llvm.x86.sse2.padds.b";
867 return "llvm.x86.sse2.padds.w";
869 return "llvm.x86.sse2.psubs.b";
871 return "llvm.x86.sse2.psubs.w";
872 case OP_PADDB_SAT_UN:
873 return "llvm.x86.sse2.paddus.b";
874 case OP_PADDW_SAT_UN:
875 return "llvm.x86.sse2.paddus.w";
876 case OP_PSUBB_SAT_UN:
877 return "llvm.x86.sse2.psubus.b";
878 case OP_PSUBW_SAT_UN:
879 return "llvm.x86.sse2.psubus.w";
881 return "llvm.x86.sse2.pavg.b";
883 return "llvm.x86.sse2.pavg.w";
885 return "llvm.x86.sse.sqrt.ps";
887 return "llvm.x86.sse2.sqrt.pd";
889 return "llvm.x86.sse.rsqrt.ps";
891 return "llvm.x86.sse.rcp.ps";
893 return "llvm.x86.sse2.cvtdq2pd";
895 return "llvm.x86.sse2.cvtdq2ps";
897 return "llvm.x86.sse2.cvtpd2dq";
899 return "llvm.x86.sse2.cvtps2dq";
901 return "llvm.x86.sse2.cvtpd2ps";
903 return "llvm.x86.sse2.cvtps2pd";
905 return "llvm.x86.sse2.cvttpd2dq";
907 return "llvm.x86.sse2.cvttps2dq";
909 return "llvm.x86.sse.cmp.ps";
911 return "llvm.x86.sse2.cmp.pd";
913 return "llvm.x86.sse2.packsswb.128";
915 return "llvm.x86.sse2.packssdw.128";
917 return "llvm.x86.sse2.packuswb.128";
919 return "llvm.x86.sse41.packusdw";
921 return "llvm.x86.sse2.pmulh.w";
922 case OP_PMULW_HIGH_UN:
923 return "llvm.x86.sse2.pmulhu.w";
926 g_assert_not_reached ();
932 simd_op_to_llvm_type (int opcode)
934 #if defined(TARGET_X86) || defined(TARGET_AMD64)
938 return type_to_simd_type (MONO_TYPE_R8);
941 return type_to_simd_type (MONO_TYPE_I8);
944 return type_to_simd_type (MONO_TYPE_I4);
949 return type_to_simd_type (MONO_TYPE_I2);
953 return type_to_simd_type (MONO_TYPE_I1);
955 return type_to_simd_type (MONO_TYPE_R4);
958 return type_to_simd_type (MONO_TYPE_I4);
962 return type_to_simd_type (MONO_TYPE_R8);
966 return type_to_simd_type (MONO_TYPE_R4);
967 case OP_EXTRACT_MASK:
968 return type_to_simd_type (MONO_TYPE_I1);
974 return type_to_simd_type (MONO_TYPE_R4);
977 return type_to_simd_type (MONO_TYPE_R8);
979 g_assert_not_reached ();
990 * Return the LLVM basic block corresponding to BB.
992 static LLVMBasicBlockRef
993 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
995 char bb_name_buf [128];
998 if (ctx->bblocks [bb->block_num].bblock == NULL) {
999 if (bb->flags & BB_EXCEPTION_HANDLER) {
1000 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1001 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1002 bb_name = bb_name_buf;
1003 } else if (bb->block_num < 256) {
1004 if (!ctx->module->bb_names) {
1005 ctx->module->bb_names_len = 256;
1006 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1008 if (!ctx->module->bb_names [bb->block_num]) {
1011 n = g_strdup_printf ("BB%d", bb->block_num);
1012 mono_memory_barrier ();
1013 ctx->module->bb_names [bb->block_num] = n;
1015 bb_name = ctx->module->bb_names [bb->block_num];
1017 sprintf (bb_name_buf, "BB%d", bb->block_num);
1018 bb_name = bb_name_buf;
1021 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1022 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1025 return ctx->bblocks [bb->block_num].bblock;
1031 * Return the last LLVM bblock corresponding to BB.
1032 * This might not be equal to the bb returned by get_bb () since we need to generate
1033 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1035 static LLVMBasicBlockRef
1036 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1039 return ctx->bblocks [bb->block_num].end_bblock;
1042 static LLVMBasicBlockRef
1043 gen_bb (EmitContext *ctx, const char *prefix)
1047 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1048 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1054 * Return the target of the patch identified by TYPE and TARGET.
1057 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1061 memset (&ji, 0, sizeof (ji));
1063 ji.data.target = target;
1065 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1071 * Emit code to convert the LLVM value V to DTYPE.
1074 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1076 LLVMTypeRef stype = LLVMTypeOf (v);
1078 if (stype != dtype) {
1079 gboolean ext = FALSE;
1082 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1084 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1086 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1090 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1092 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1093 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1096 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1097 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1098 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1099 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1100 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1101 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1102 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1103 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1105 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1106 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1107 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1108 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1109 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1110 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1112 if (mono_arch_is_soft_float ()) {
1113 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1114 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1115 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1116 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1119 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1120 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1123 LLVMDumpValue (LLVMConstNull (dtype));
1124 g_assert_not_reached ();
1132 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1134 return convert_full (ctx, v, dtype, FALSE);
1138 * emit_volatile_load:
1140 * If vreg is volatile, emit a load from its address.
1143 emit_volatile_load (EmitContext *ctx, int vreg)
1147 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1148 t = ctx->vreg_cli_types [vreg];
1149 if (t && !t->byref) {
1151 * Might have to zero extend since llvm doesn't have
1154 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1155 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1156 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1157 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1158 else if (t->type == MONO_TYPE_U8)
1159 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1166 * emit_volatile_store:
1168 * If VREG is volatile, emit a store from its value to its address.
1171 emit_volatile_store (EmitContext *ctx, int vreg)
1173 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1175 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1176 g_assert (ctx->addresses [vreg]);
1177 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1182 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1184 LLVMTypeRef ret_type;
1185 LLVMTypeRef *param_types = NULL;
1190 rtype = mini_get_underlying_type (sig->ret);
1191 ret_type = type_to_llvm_type (ctx, rtype);
1195 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1199 param_types [pindex ++] = ThisType ();
1200 for (i = 0; i < sig->param_count; ++i)
1201 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1203 if (!ctx_ok (ctx)) {
1204 g_free (param_types);
1208 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1209 g_free (param_types);
1215 * sig_to_llvm_sig_full:
1217 * Return the LLVM signature corresponding to the mono signature SIG using the
1218 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1221 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1223 LLVMTypeRef ret_type;
1224 LLVMTypeRef *param_types = NULL;
1226 int i, j, pindex, vret_arg_pindex = 0;
1227 gboolean vretaddr = FALSE;
1231 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1233 rtype = mini_get_underlying_type (sig->ret);
1234 ret_type = type_to_llvm_type (ctx, rtype);
1238 switch (cinfo->ret.storage) {
1239 case LLVMArgVtypeInReg:
1240 /* LLVM models this by returning an aggregate value */
1241 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1242 LLVMTypeRef members [2];
1244 members [0] = IntPtrType ();
1245 ret_type = LLVMStructType (members, 1, FALSE);
1246 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1248 ret_type = LLVMVoidType ();
1249 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1250 LLVMTypeRef members [2];
1252 members [0] = IntPtrType ();
1253 members [1] = IntPtrType ();
1254 ret_type = LLVMStructType (members, 2, FALSE);
1256 g_assert_not_reached ();
1259 case LLVMArgVtypeByVal:
1260 /* Vtype returned normally by val */
1262 case LLVMArgVtypeAsScalar: {
1263 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1264 /* LLVM models this by returning an int */
1265 if (size < SIZEOF_VOID_P) {
1266 g_assert (cinfo->ret.nslots == 1);
1267 ret_type = LLVMIntType (size * 8);
1269 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1270 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1274 case LLVMArgFpStruct: {
1275 /* Vtype returned as a fp struct */
1276 LLVMTypeRef members [16];
1278 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1279 for (i = 0; i < cinfo->ret.nslots; ++i)
1280 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1281 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1284 case LLVMArgVtypeByRef:
1285 /* Vtype returned using a hidden argument */
1286 ret_type = LLVMVoidType ();
1288 case LLVMArgVtypeRetAddr:
1289 case LLVMArgScalarRetAddr:
1290 case LLVMArgGsharedvtFixed:
1291 case LLVMArgGsharedvtFixedVtype:
1292 case LLVMArgGsharedvtVariable:
1294 ret_type = LLVMVoidType ();
1300 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1302 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1304 * Has to be the first argument because of the sret argument attribute
1305 * FIXME: This might conflict with passing 'this' as the first argument, but
1306 * this is only used on arm64 which has a dedicated struct return register.
1308 cinfo->vret_arg_pindex = pindex;
1309 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1310 if (!ctx_ok (ctx)) {
1311 g_free (param_types);
1314 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1317 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1318 cinfo->rgctx_arg_pindex = pindex;
1319 param_types [pindex] = ctx->module->ptr_type;
1322 if (cinfo->imt_arg) {
1323 cinfo->imt_arg_pindex = pindex;
1324 param_types [pindex] = ctx->module->ptr_type;
1328 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1329 vret_arg_pindex = pindex;
1330 if (cinfo->vret_arg_index == 1) {
1331 /* Add the slots consumed by the first argument */
1332 LLVMArgInfo *ainfo = &cinfo->args [0];
1333 switch (ainfo->storage) {
1334 case LLVMArgVtypeInReg:
1335 for (j = 0; j < 2; ++j) {
1336 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1345 cinfo->vret_arg_pindex = vret_arg_pindex;
1348 if (vretaddr && vret_arg_pindex == pindex)
1349 param_types [pindex ++] = IntPtrType ();
1351 cinfo->this_arg_pindex = pindex;
1352 param_types [pindex ++] = ThisType ();
1353 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1355 if (vretaddr && vret_arg_pindex == pindex)
1356 param_types [pindex ++] = IntPtrType ();
1357 for (i = 0; i < sig->param_count; ++i) {
1358 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1360 if (vretaddr && vret_arg_pindex == pindex)
1361 param_types [pindex ++] = IntPtrType ();
1362 ainfo->pindex = pindex;
1364 switch (ainfo->storage) {
1365 case LLVMArgVtypeInReg:
1366 for (j = 0; j < 2; ++j) {
1367 switch (ainfo->pair_storage [j]) {
1369 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1374 g_assert_not_reached ();
1378 case LLVMArgVtypeByVal:
1379 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1382 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1385 case LLVMArgAsIArgs:
1386 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1389 case LLVMArgVtypeByRef:
1390 case LLVMArgScalarByRef:
1391 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1394 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1397 case LLVMArgAsFpArgs: {
1400 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1401 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1402 param_types [pindex ++] = LLVMDoubleType ();
1403 for (j = 0; j < ainfo->nslots; ++j)
1404 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1407 case LLVMArgVtypeAsScalar:
1408 g_assert_not_reached ();
1410 case LLVMArgGsharedvtFixed:
1411 case LLVMArgGsharedvtFixedVtype:
1412 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1414 case LLVMArgGsharedvtVariable:
1415 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1418 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1422 if (!ctx_ok (ctx)) {
1423 g_free (param_types);
1426 if (vretaddr && vret_arg_pindex == pindex)
1427 param_types [pindex ++] = IntPtrType ();
1428 if (ctx->llvm_only && cinfo->rgctx_arg) {
1429 /* Pass the rgctx as the last argument */
1430 cinfo->rgctx_arg_pindex = pindex;
1431 param_types [pindex] = ctx->module->ptr_type;
1435 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1436 g_free (param_types);
1442 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1444 return sig_to_llvm_sig_full (ctx, sig, NULL);
1448 * LLVMFunctionType1:
1450 * Create an LLVM function type from the arguments.
1452 static G_GNUC_UNUSED LLVMTypeRef
1453 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1456 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1460 * LLVMFunctionType1:
1462 * Create an LLVM function type from the arguments.
1464 static G_GNUC_UNUSED LLVMTypeRef
1465 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1466 LLVMTypeRef ParamType1,
1469 LLVMTypeRef param_types [1];
1471 param_types [0] = ParamType1;
1473 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1477 * LLVMFunctionType2:
1479 * Create an LLVM function type from the arguments.
1481 static G_GNUC_UNUSED LLVMTypeRef
1482 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1483 LLVMTypeRef ParamType1,
1484 LLVMTypeRef ParamType2,
1487 LLVMTypeRef param_types [2];
1489 param_types [0] = ParamType1;
1490 param_types [1] = ParamType2;
1492 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1496 * LLVMFunctionType3:
1498 * Create an LLVM function type from the arguments.
1500 static G_GNUC_UNUSED LLVMTypeRef
1501 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1502 LLVMTypeRef ParamType1,
1503 LLVMTypeRef ParamType2,
1504 LLVMTypeRef ParamType3,
1507 LLVMTypeRef param_types [3];
1509 param_types [0] = ParamType1;
1510 param_types [1] = ParamType2;
1511 param_types [2] = ParamType3;
1513 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1516 static G_GNUC_UNUSED LLVMTypeRef
1517 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1518 LLVMTypeRef ParamType1,
1519 LLVMTypeRef ParamType2,
1520 LLVMTypeRef ParamType3,
1521 LLVMTypeRef ParamType4,
1522 LLVMTypeRef ParamType5,
1525 LLVMTypeRef param_types [5];
1527 param_types [0] = ParamType1;
1528 param_types [1] = ParamType2;
1529 param_types [2] = ParamType3;
1530 param_types [3] = ParamType4;
1531 param_types [4] = ParamType5;
1533 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1539 * Create an LLVM builder and remember it so it can be freed later.
1541 static LLVMBuilderRef
1542 create_builder (EmitContext *ctx)
1544 LLVMBuilderRef builder = LLVMCreateBuilder ();
1546 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1552 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1557 case MONO_PATCH_INFO_INTERNAL_METHOD:
1558 name = g_strdup_printf ("jit_icall_%s", data);
1560 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1561 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1562 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1566 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1574 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1578 LLVMValueRef indexes [2];
1580 LLVMValueRef got_entry_addr, load;
1581 LLVMBuilderRef builder = ctx->builder;
1586 ji = g_new0 (MonoJumpInfo, 1);
1588 ji->data.target = data;
1590 ji = mono_aot_patch_info_dup (ji);
1592 ji->next = cfg->patch_info;
1593 cfg->patch_info = ji;
1595 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1596 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1598 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1599 * explicitly initialize it.
1601 if (!mono_aot_is_shared_got_offset (got_offset)) {
1602 //mono_print_ji (ji);
1604 ctx->has_got_access = TRUE;
1607 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1608 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1609 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1611 name = get_aotconst_name (type, data, got_offset);
1613 load = LLVMBuildLoad (builder, got_entry_addr, "");
1614 load = convert (ctx, load, llvm_type);
1615 LLVMSetValueName (load, name ? name : "");
1617 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1620 //set_invariant_load_flag (load);
1626 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1628 return get_aotconst_typed (ctx, type, data, NULL);
1632 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1634 LLVMValueRef callee;
1636 if (ctx->llvm_only) {
1637 callee_name = mono_aot_get_direct_call_symbol (type, data);
1639 /* Directly callable */
1641 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1643 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1645 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1647 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1649 /* LLVMTypeRef's are uniqued */
1650 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1651 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1653 g_free (callee_name);
1659 * Calls are made through the GOT.
1661 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1663 MonoJumpInfo *ji = NULL;
1665 callee_name = mono_aot_get_plt_symbol (type, data);
1669 if (ctx->cfg->compile_aot)
1670 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1671 mono_add_patch_info (ctx->cfg, 0, type, data);
1674 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1676 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1678 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1680 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1683 if (ctx->cfg->compile_aot) {
1684 ji = g_new0 (MonoJumpInfo, 1);
1686 ji->data.target = data;
1688 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1696 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1698 MonoMethodHeader *header = cfg->header;
1699 MonoExceptionClause *clause;
1703 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1704 return (bb->region >> 8) - 1;
1707 for (i = 0; i < header->num_clauses; ++i) {
1708 clause = &header->clauses [i];
1710 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1717 static MonoExceptionClause *
1718 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1720 // Since they're sorted by nesting we just need
1721 // the first one that the bb is a member of
1722 MonoExceptionClause *last = NULL;
1724 for (int i = 0; i < cfg->header->num_clauses; i++) {
1725 MonoExceptionClause *curr = &cfg->header->clauses [i];
1727 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1730 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1731 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1745 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1747 LLVMValueRef md_arg;
1750 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1751 md_arg = LLVMMDString ("mono", 4);
1752 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1756 set_invariant_load_flag (LLVMValueRef v)
1758 LLVMValueRef md_arg;
1760 const char *flag_name;
1762 // FIXME: Cache this
1763 flag_name = "invariant.load";
1764 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1765 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1766 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1772 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1776 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1778 MonoCompile *cfg = ctx->cfg;
1779 LLVMValueRef lcall = NULL;
1780 LLVMBuilderRef builder = *builder_ref;
1781 MonoExceptionClause *clause;
1783 if (ctx->llvm_only) {
1784 clause = get_most_deep_clause (cfg, ctx, bb);
1787 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1790 * Have to use an invoke instead of a call, branching to the
1791 * handler bblock of the clause containing this bblock.
1793 intptr_t key = CLAUSE_END(clause);
1795 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1797 // FIXME: Find the one that has the lowest end bound for the right start address
1798 // FIXME: Finally + nesting
1801 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1804 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1806 builder = ctx->builder = create_builder (ctx);
1807 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1809 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1813 int clause_index = get_handler_clause (cfg, bb);
1815 if (clause_index != -1) {
1816 MonoMethodHeader *header = cfg->header;
1817 MonoExceptionClause *ec = &header->clauses [clause_index];
1818 MonoBasicBlock *tblock;
1819 LLVMBasicBlockRef ex_bb, noex_bb;
1822 * Have to use an invoke instead of a call, branching to the
1823 * handler bblock of the clause containing this bblock.
1826 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1828 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1831 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1833 ex_bb = get_bb (ctx, tblock);
1835 noex_bb = gen_bb (ctx, "NOEX_BB");
1838 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1840 builder = ctx->builder = create_builder (ctx);
1841 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1843 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1848 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1849 ctx->builder = builder;
1853 *builder_ref = ctx->builder;
1859 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1861 const char *intrins_name;
1862 LLVMValueRef args [16], res;
1863 LLVMTypeRef addr_type;
1865 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1866 LLVMAtomicOrdering ordering;
1869 case LLVM_BARRIER_NONE:
1870 ordering = LLVMAtomicOrderingNotAtomic;
1872 case LLVM_BARRIER_ACQ:
1873 ordering = LLVMAtomicOrderingAcquire;
1875 case LLVM_BARRIER_SEQ:
1876 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1879 g_assert_not_reached ();
1884 * We handle loads which can fault by calling a mono specific intrinsic
1885 * using an invoke, so they are handled properly inside try blocks.
1886 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1887 * are marked with IntrReadArgMem.
1891 intrins_name = "llvm.mono.load.i8.p0i8";
1894 intrins_name = "llvm.mono.load.i16.p0i16";
1897 intrins_name = "llvm.mono.load.i32.p0i32";
1900 intrins_name = "llvm.mono.load.i64.p0i64";
1903 g_assert_not_reached ();
1906 addr_type = LLVMTypeOf (addr);
1907 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1908 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1911 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1912 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1913 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1914 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1916 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1917 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1918 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1919 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1926 * We emit volatile loads for loads which can fault, because otherwise
1927 * LLVM will generate invalid code when encountering a load from a
1930 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1932 /* Mark it with a custom metadata */
1935 set_metadata_flag (res, "mono.faulting.load");
1943 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1945 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1949 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1951 const char *intrins_name;
1952 LLVMValueRef args [16];
1954 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1955 LLVMAtomicOrdering ordering;
1958 case LLVM_BARRIER_NONE:
1959 ordering = LLVMAtomicOrderingNotAtomic;
1961 case LLVM_BARRIER_REL:
1962 ordering = LLVMAtomicOrderingRelease;
1964 case LLVM_BARRIER_SEQ:
1965 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1968 g_assert_not_reached ();
1974 intrins_name = "llvm.mono.store.i8.p0i8";
1977 intrins_name = "llvm.mono.store.i16.p0i16";
1980 intrins_name = "llvm.mono.store.i32.p0i32";
1983 intrins_name = "llvm.mono.store.i64.p0i64";
1986 g_assert_not_reached ();
1989 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1990 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1991 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1996 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1997 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1998 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1999 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2001 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2006 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2008 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2012 * emit_cond_system_exception:
2014 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2015 * Might set the ctx exception.
2018 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2020 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2021 LLVMBuilderRef builder;
2022 MonoClass *exc_class;
2023 LLVMValueRef args [2];
2024 LLVMValueRef callee;
2026 ex_bb = gen_bb (ctx, "EX_BB");
2028 ex2_bb = gen_bb (ctx, "EX2_BB");
2029 noex_bb = gen_bb (ctx, "NOEX_BB");
2031 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2033 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2034 g_assert (exc_class);
2036 /* Emit exception throwing code */
2037 ctx->builder = builder = create_builder (ctx);
2038 LLVMPositionBuilderAtEnd (builder, ex_bb);
2040 if (ctx->cfg->llvm_only) {
2041 static LLVMTypeRef sig;
2044 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2045 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2047 LLVMBuildBr (builder, ex2_bb);
2049 ctx->builder = builder = create_builder (ctx);
2050 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2052 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2053 emit_call (ctx, bb, &builder, callee, args, 1);
2054 LLVMBuildUnreachable (builder);
2056 ctx->builder = builder = create_builder (ctx);
2057 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2059 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2065 callee = ctx->module->throw_corlib_exception;
2068 const char *icall_name;
2070 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2071 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2073 if (ctx->cfg->compile_aot) {
2074 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2076 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2079 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2080 * - On x86, LLVM generated code doesn't push the arguments
2081 * - The trampoline takes the throw address as an arguments, not a pc offset.
2083 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2085 mono_memory_barrier ();
2086 ctx->module->throw_corlib_exception = callee;
2090 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2091 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2093 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2096 * The LLVM mono branch contains changes so a block address can be passed as an
2097 * argument to a call.
2099 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2100 emit_call (ctx, bb, &builder, callee, args, 2);
2102 LLVMBuildUnreachable (builder);
2104 ctx->builder = builder = create_builder (ctx);
2105 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2107 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2114 * emit_args_to_vtype:
2116 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2119 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2121 int j, size, nslots;
2123 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2125 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2126 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2129 if (ainfo->storage == LLVMArgAsFpArgs)
2130 nslots = ainfo->nslots;
2134 for (j = 0; j < nslots; ++j) {
2135 LLVMValueRef index [2], addr, daddr;
2136 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2137 LLVMTypeRef part_type;
2139 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2142 if (ainfo->pair_storage [j] == LLVMArgNone)
2145 switch (ainfo->pair_storage [j]) {
2146 case LLVMArgInIReg: {
2147 part_type = LLVMIntType (part_size * 8);
2148 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2149 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2150 addr = LLVMBuildGEP (builder, address, index, 1, "");
2152 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2153 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2154 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2156 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2159 case LLVMArgInFPReg: {
2160 LLVMTypeRef arg_type;
2162 if (ainfo->esize == 8)
2163 arg_type = LLVMDoubleType ();
2165 arg_type = LLVMFloatType ();
2167 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2168 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2169 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2170 LLVMBuildStore (builder, args [j], addr);
2176 g_assert_not_reached ();
2179 size -= sizeof (gpointer);
2184 * emit_vtype_to_args:
2186 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2187 * into ARGS, and the number of arguments into NARGS.
2190 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2193 int j, size, nslots;
2194 LLVMTypeRef arg_type;
2196 size = get_vtype_size (t);
2198 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2199 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2201 if (ainfo->storage == LLVMArgAsFpArgs)
2202 nslots = ainfo->nslots;
2205 for (j = 0; j < nslots; ++j) {
2206 LLVMValueRef index [2], addr, daddr;
2207 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2209 if (ainfo->pair_storage [j] == LLVMArgNone)
2212 switch (ainfo->pair_storage [j]) {
2214 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2215 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2216 addr = LLVMBuildGEP (builder, address, index, 1, "");
2218 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2219 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2220 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2222 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2224 case LLVMArgInFPReg:
2225 if (ainfo->esize == 8)
2226 arg_type = LLVMDoubleType ();
2228 arg_type = LLVMFloatType ();
2229 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2230 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2231 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2232 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2237 g_assert_not_reached ();
2239 size -= sizeof (gpointer);
2246 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2249 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2250 * get executed every time control reaches them.
2252 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2254 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2255 return ctx->last_alloca;
2259 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2261 return build_alloca_llvm_type_name (ctx, t, align, "");
2265 build_alloca (EmitContext *ctx, MonoType *t)
2267 MonoClass *k = mono_class_from_mono_type (t);
2270 g_assert (!mini_is_gsharedvt_variable_type (t));
2272 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2275 align = mono_class_min_align (k);
2277 /* Sometimes align is not a power of 2 */
2278 while (mono_is_power_of_two (align) == -1)
2281 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2285 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2289 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2291 MonoCompile *cfg = ctx->cfg;
2292 LLVMBuilderRef builder = ctx->builder;
2293 LLVMValueRef offset, offset_var;
2294 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2295 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2299 g_assert (info_var);
2300 g_assert (locals_var);
2302 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2304 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2305 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2307 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2308 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2310 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2314 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2317 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2320 module->used = g_ptr_array_sized_new (16);
2321 g_ptr_array_add (module->used, global);
2325 emit_llvm_used (MonoLLVMModule *module)
2327 LLVMModuleRef lmodule = module->lmodule;
2328 LLVMTypeRef used_type;
2329 LLVMValueRef used, *used_elem;
2335 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2336 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2337 used_elem = g_new0 (LLVMValueRef, module->used->len);
2338 for (i = 0; i < module->used->len; ++i)
2339 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2340 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2341 LLVMSetLinkage (used, LLVMAppendingLinkage);
2342 LLVMSetSection (used, "llvm.metadata");
2348 * Emit a function mapping method indexes to their code
2351 emit_get_method (MonoLLVMModule *module)
2353 LLVMModuleRef lmodule = module->lmodule;
2354 LLVMValueRef func, switch_ins, m;
2355 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2356 LLVMBasicBlockRef *bbs;
2358 LLVMBuilderRef builder;
2363 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2364 * but generating code seems safer.
2366 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2367 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2368 LLVMSetLinkage (func, LLVMExternalLinkage);
2369 LLVMSetVisibility (func, LLVMHiddenVisibility);
2370 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2371 module->get_method = func;
2373 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2376 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2377 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2378 * then we will have to find another solution.
2381 name = g_strdup_printf ("BB_CODE_START");
2382 code_start_bb = LLVMAppendBasicBlock (func, name);
2384 builder = LLVMCreateBuilder ();
2385 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2386 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2388 name = g_strdup_printf ("BB_CODE_END");
2389 code_end_bb = LLVMAppendBasicBlock (func, name);
2391 builder = LLVMCreateBuilder ();
2392 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2393 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2395 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2396 for (i = 0; i < module->max_method_idx + 1; ++i) {
2397 name = g_strdup_printf ("BB_%d", i);
2398 bb = LLVMAppendBasicBlock (func, name);
2402 builder = LLVMCreateBuilder ();
2403 LLVMPositionBuilderAtEnd (builder, bb);
2405 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2407 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2409 LLVMBuildRet (builder, LLVMConstNull (rtype));
2412 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2413 builder = LLVMCreateBuilder ();
2414 LLVMPositionBuilderAtEnd (builder, fail_bb);
2415 LLVMBuildRet (builder, LLVMConstNull (rtype));
2417 builder = LLVMCreateBuilder ();
2418 LLVMPositionBuilderAtEnd (builder, entry_bb);
2420 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2421 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2422 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2423 for (i = 0; i < module->max_method_idx + 1; ++i) {
2424 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2427 mark_as_used (module, func);
2431 * emit_get_unbox_tramp:
2433 * Emit a function mapping method indexes to their unbox trampoline
2436 emit_get_unbox_tramp (MonoLLVMModule *module)
2438 LLVMModuleRef lmodule = module->lmodule;
2439 LLVMValueRef func, switch_ins, m;
2440 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2441 LLVMBasicBlockRef *bbs;
2443 LLVMBuilderRef builder;
2447 /* Similar to emit_get_method () */
2449 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2450 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2451 LLVMSetLinkage (func, LLVMExternalLinkage);
2452 LLVMSetVisibility (func, LLVMHiddenVisibility);
2453 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2454 module->get_unbox_tramp = func;
2456 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2458 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2459 for (i = 0; i < module->max_method_idx + 1; ++i) {
2460 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2464 name = g_strdup_printf ("BB_%d", i);
2465 bb = LLVMAppendBasicBlock (func, name);
2469 builder = LLVMCreateBuilder ();
2470 LLVMPositionBuilderAtEnd (builder, bb);
2472 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2475 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2476 builder = LLVMCreateBuilder ();
2477 LLVMPositionBuilderAtEnd (builder, fail_bb);
2478 LLVMBuildRet (builder, LLVMConstNull (rtype));
2480 builder = LLVMCreateBuilder ();
2481 LLVMPositionBuilderAtEnd (builder, entry_bb);
2483 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2484 for (i = 0; i < module->max_method_idx + 1; ++i) {
2485 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2489 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2492 mark_as_used (module, func);
2495 /* Add a function to mark the beginning of LLVM code */
2497 emit_llvm_code_start (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2501 LLVMBasicBlockRef entry_bb;
2502 LLVMBuilderRef builder;
2504 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2505 LLVMSetLinkage (func, LLVMInternalLinkage);
2506 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2507 module->code_start = func;
2508 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2509 builder = LLVMCreateBuilder ();
2510 LLVMPositionBuilderAtEnd (builder, entry_bb);
2511 LLVMBuildRetVoid (builder);
2515 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2517 LLVMModuleRef lmodule = module->lmodule;
2518 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2519 LLVMBasicBlockRef entry_bb;
2520 LLVMBuilderRef builder;
2527 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2528 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2533 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2534 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2537 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2538 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2541 g_assert_not_reached ();
2543 LLVMSetLinkage (func, LLVMInternalLinkage);
2544 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2545 mono_llvm_set_preserveall_cc (func);
2546 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2547 builder = LLVMCreateBuilder ();
2548 LLVMPositionBuilderAtEnd (builder, entry_bb);
2551 ji = g_new0 (MonoJumpInfo, 1);
2552 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2553 ji = mono_aot_patch_info_dup (ji);
2554 got_offset = mono_aot_get_got_offset (ji);
2555 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2556 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2557 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2558 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2559 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2560 args [1] = LLVMGetParam (func, 0);
2562 args [2] = LLVMGetParam (func, 1);
2564 ji = g_new0 (MonoJumpInfo, 1);
2565 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2566 ji->data.name = icall_name;
2567 ji = mono_aot_patch_info_dup (ji);
2568 got_offset = mono_aot_get_got_offset (ji);
2569 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2570 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2571 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2572 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2573 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2574 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2575 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2577 // Set the inited flag
2578 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2579 indexes [1] = LLVMGetParam (func, 0);
2580 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2582 LLVMBuildRetVoid (builder);
2584 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2589 * Emit wrappers around the C icalls used to initialize llvm methods, to
2590 * make the calling code smaller and to enable usage of the llvm
2591 * PreserveAll calling convention.
2594 emit_init_icall_wrappers (MonoLLVMModule *module)
2596 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2597 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2598 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2599 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2603 emit_llvm_code_end (MonoLLVMModule *module)
2605 LLVMModuleRef lmodule = module->lmodule;
2607 LLVMBasicBlockRef entry_bb;
2608 LLVMBuilderRef builder;
2610 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2611 LLVMSetLinkage (func, LLVMInternalLinkage);
2612 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2613 module->code_end = func;
2614 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2615 builder = LLVMCreateBuilder ();
2616 LLVMPositionBuilderAtEnd (builder, entry_bb);
2617 LLVMBuildRetVoid (builder);
2621 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2623 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2626 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2627 need_div_check = TRUE;
2629 if (!need_div_check)
2632 switch (ins->opcode) {
2645 case OP_IDIV_UN_IMM:
2646 case OP_LDIV_UN_IMM:
2647 case OP_IREM_UN_IMM:
2648 case OP_LREM_UN_IMM: {
2650 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2651 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2653 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2654 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2657 builder = ctx->builder;
2659 /* b == -1 && a == 0x80000000 */
2661 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2662 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2663 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2665 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2666 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2669 builder = ctx->builder;
2681 * Emit code to initialize the GOT slots used by the method.
2684 emit_init_method (EmitContext *ctx)
2686 LLVMValueRef indexes [16], args [16], callee;
2687 LLVMValueRef inited_var, cmp, call;
2688 LLVMBasicBlockRef inited_bb, notinited_bb;
2689 LLVMBuilderRef builder = ctx->builder;
2690 MonoCompile *cfg = ctx->cfg;
2692 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2694 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2695 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2696 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2698 args [0] = inited_var;
2699 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2700 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2702 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2704 inited_bb = ctx->inited_bb;
2705 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2707 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2709 builder = ctx->builder = create_builder (ctx);
2710 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2713 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2714 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2715 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2716 callee = ctx->module->init_method_gshared_mrgctx;
2717 call = LLVMBuildCall (builder, callee, args, 2, "");
2718 } else if (ctx->rgctx_arg) {
2719 /* A vtable is passed as the rgctx argument */
2720 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2721 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2722 callee = ctx->module->init_method_gshared_vtable;
2723 call = LLVMBuildCall (builder, callee, args, 2, "");
2724 } else if (cfg->gshared) {
2725 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2726 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2727 callee = ctx->module->init_method_gshared_this;
2728 call = LLVMBuildCall (builder, callee, args, 2, "");
2730 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2731 callee = ctx->module->init_method;
2732 call = LLVMBuildCall (builder, callee, args, 1, "");
2736 * This enables llvm to keep arguments in their original registers/
2737 * scratch registers, since the call will not clobber them.
2739 mono_llvm_set_call_preserveall_cc (call);
2741 LLVMBuildBr (builder, inited_bb);
2742 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2744 builder = ctx->builder = create_builder (ctx);
2745 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2749 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2752 * Emit unbox trampoline using a tail call
2754 LLVMValueRef tramp, call, *args;
2755 LLVMBuilderRef builder;
2756 LLVMBasicBlockRef lbb;
2757 LLVMCallInfo *linfo;
2761 tramp_name = g_strdup_printf ("ut_%s", method_name);
2762 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2763 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2764 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2765 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2767 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2768 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2769 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2770 if (ctx->cfg->vret_addr) {
2771 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2772 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2773 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2774 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2778 lbb = LLVMAppendBasicBlock (tramp, "");
2779 builder = LLVMCreateBuilder ();
2780 LLVMPositionBuilderAtEnd (builder, lbb);
2782 nargs = LLVMCountParamTypes (method_type);
2783 args = g_new0 (LLVMValueRef, nargs);
2784 for (i = 0; i < nargs; ++i) {
2785 args [i] = LLVMGetParam (tramp, i);
2786 if (i == ctx->this_arg_pindex) {
2787 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2789 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2790 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2791 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2794 call = LLVMBuildCall (builder, method, args, nargs, "");
2795 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2796 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2797 if (linfo->ret.storage == LLVMArgVtypeByRef)
2798 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2800 // FIXME: This causes assertions in clang
2801 //mono_llvm_set_must_tail (call);
2802 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2803 LLVMBuildRetVoid (builder);
2805 LLVMBuildRet (builder, call);
2807 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2813 * Emit code to load/convert arguments.
2816 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2819 MonoCompile *cfg = ctx->cfg;
2820 MonoMethodSignature *sig = ctx->sig;
2821 LLVMCallInfo *linfo = ctx->linfo;
2825 LLVMBuilderRef old_builder = ctx->builder;
2826 ctx->builder = builder;
2828 ctx->alloca_builder = create_builder (ctx);
2831 * Handle indirect/volatile variables by allocating memory for them
2832 * using 'alloca', and storing their address in a temporary.
2834 for (i = 0; i < cfg->num_varinfo; ++i) {
2835 MonoInst *var = cfg->varinfo [i];
2838 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2839 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2840 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2843 /* Could be already created by an OP_VPHI */
2844 if (!ctx->addresses [var->dreg]) {
2845 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2846 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2848 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2852 names = g_new (char *, sig->param_count);
2853 mono_method_get_param_names (cfg->method, (const char **) names);
2855 for (i = 0; i < sig->param_count; ++i) {
2856 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2857 int reg = cfg->args [i + sig->hasthis]->dreg;
2860 pindex = ainfo->pindex;
2862 switch (ainfo->storage) {
2863 case LLVMArgVtypeInReg:
2864 case LLVMArgAsFpArgs: {
2865 LLVMValueRef args [8];
2868 pindex += ainfo->ndummy_fpargs;
2870 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2871 memset (args, 0, sizeof (args));
2872 if (ainfo->storage == LLVMArgVtypeInReg) {
2873 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2874 if (ainfo->pair_storage [1] != LLVMArgNone)
2875 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2877 g_assert (ainfo->nslots <= 8);
2878 for (j = 0; j < ainfo->nslots; ++j)
2879 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2881 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2883 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2885 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2886 /* Treat these as normal values */
2887 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2891 case LLVMArgVtypeByVal: {
2892 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2894 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2895 /* Treat these as normal values */
2896 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2900 case LLVMArgVtypeByRef: {
2901 /* The argument is passed by ref */
2902 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2905 case LLVMArgScalarByRef: {
2907 name = g_strdup_printf ("arg_%s", names [i]);
2909 name = g_strdup_printf ("arg_%d", i);
2910 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2914 case LLVMArgAsIArgs: {
2915 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2918 /* The argument is received as an array of ints, store it into the real argument */
2919 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2921 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2922 if (size < SIZEOF_VOID_P) {
2923 /* The upper bits of the registers might not be valid */
2924 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2925 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2926 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2928 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2932 case LLVMArgVtypeAsScalar:
2933 g_assert_not_reached ();
2935 case LLVMArgGsharedvtFixed: {
2936 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2937 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2940 name = g_strdup_printf ("arg_%s", names [i]);
2942 name = g_strdup_printf ("arg_%d", i);
2944 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2947 case LLVMArgGsharedvtFixedVtype: {
2948 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2951 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2953 name = g_strdup_printf ("vtype_arg_%d", i);
2955 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2956 g_assert (ctx->addresses [reg]);
2957 LLVMSetValueName (ctx->addresses [reg], name);
2958 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2961 case LLVMArgGsharedvtVariable:
2962 /* The IR treats these as variables with addresses */
2963 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2966 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
2973 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2975 emit_volatile_store (ctx, cfg->args [0]->dreg);
2976 for (i = 0; i < sig->param_count; ++i)
2977 if (!mini_type_is_vtype (sig->params [i]))
2978 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2980 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2981 LLVMValueRef this_alloc;
2984 * The exception handling code needs the location where the this argument was
2985 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2986 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2987 * location into the LSDA.
2989 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2990 /* This volatile store will keep the alloca alive */
2991 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2993 set_metadata_flag (this_alloc, "mono.this");
2996 if (cfg->rgctx_var) {
2997 LLVMValueRef rgctx_alloc, store;
3000 * We handle the rgctx arg similarly to the this pointer.
3002 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3003 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3004 /* This volatile store will keep the alloca alive */
3005 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3007 set_metadata_flag (rgctx_alloc, "mono.this");
3010 /* Initialize the method if needed */
3011 if (cfg->compile_aot && ctx->llvm_only) {
3012 /* Emit a location for the initialization code */
3013 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3014 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3016 LLVMBuildBr (ctx->builder, ctx->init_bb);
3017 builder = ctx->builder = create_builder (ctx);
3018 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3019 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3022 /* Compute nesting between clauses */
3023 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3024 for (i = 0; i < cfg->header->num_clauses; ++i) {
3025 for (j = 0; j < cfg->header->num_clauses; ++j) {
3026 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3027 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3029 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3030 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3035 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3036 * it needs to continue normally, or return back to the exception handling system.
3038 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3042 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3045 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3046 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3047 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3049 if (bb->in_scount == 0) {
3052 sprintf (name, "finally_ind_bb%d", bb->block_num);
3053 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3054 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3056 ctx->bblocks [bb->block_num].finally_ind = val;
3058 /* Create a variable to hold the exception var */
3060 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3064 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3065 * LLVM bblock containing a landing pad causes problems for the
3066 * LLVM optimizer passes.
3068 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3069 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3071 ctx->builder = old_builder;
3075 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3077 MonoCompile *cfg = ctx->cfg;
3078 LLVMModuleRef lmodule = ctx->lmodule;
3079 LLVMValueRef *values = ctx->values;
3080 LLVMValueRef *addresses = ctx->addresses;
3081 MonoCallInst *call = (MonoCallInst*)ins;
3082 MonoMethodSignature *sig = call->signature;
3083 LLVMValueRef callee = NULL, lcall;
3085 LLVMCallInfo *cinfo;
3089 LLVMTypeRef llvm_sig;
3091 gboolean is_virtual, calli, preserveall;
3092 LLVMBuilderRef builder = *builder_ref;
3094 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3095 set_failure (ctx, "non-default callconv");
3099 cinfo = call->cinfo;
3101 if (call->rgctx_arg_reg)
3102 cinfo->rgctx_arg = TRUE;
3103 if (call->imt_arg_reg)
3104 cinfo->imt_arg = TRUE;
3106 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3108 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3112 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3113 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3115 preserveall = FALSE;
3117 /* FIXME: Avoid creating duplicate methods */
3119 if (ins->flags & MONO_INST_HAS_METHOD) {
3123 if (cfg->compile_aot) {
3124 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3126 set_failure (ctx, "can't encode patch");
3129 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3131 * Collect instructions representing the callee into a hash so they can be replaced
3132 * by the llvm method for the callee if the callee turns out to be direct
3133 * callable. Currently this only requires it to not fail llvm compilation.
3135 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3136 l = g_slist_prepend (l, callee);
3137 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3140 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3143 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3145 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3149 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3150 /* LLVM miscompiles async methods */
3151 set_failure (ctx, "#13734");
3156 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3162 memset (&ji, 0, sizeof (ji));
3163 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3164 ji.data.target = info->name;
3166 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3168 if (cfg->compile_aot) {
3169 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3171 set_failure (ctx, "can't encode patch");
3175 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3176 target = (gpointer)mono_icall_get_wrapper (info);
3177 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3180 if (cfg->compile_aot) {
3182 if (cfg->abs_patches) {
3183 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3185 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3187 set_failure (ctx, "can't encode patch");
3193 set_failure (ctx, "aot");
3197 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3199 if (cfg->abs_patches) {
3200 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3203 * FIXME: Some trampolines might have
3204 * their own calling convention on some platforms.
3206 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3207 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3211 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3217 int size = sizeof (gpointer);
3220 g_assert (ins->inst_offset % size == 0);
3221 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3223 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3225 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3227 if (ins->flags & MONO_INST_HAS_METHOD) {
3232 * Collect and convert arguments
3234 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3235 len = sizeof (LLVMValueRef) * nargs;
3236 args = (LLVMValueRef*)alloca (len);
3237 memset (args, 0, len);
3238 l = call->out_ireg_args;
3240 if (call->rgctx_arg_reg) {
3241 g_assert (values [call->rgctx_arg_reg]);
3242 g_assert (cinfo->rgctx_arg_pindex < nargs);
3244 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3245 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3246 * it using a volatile load.
3249 if (!ctx->imt_rgctx_loc)
3250 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3251 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3252 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3254 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3257 if (call->imt_arg_reg) {
3258 g_assert (!ctx->llvm_only);
3259 g_assert (values [call->imt_arg_reg]);
3260 g_assert (cinfo->imt_arg_pindex < nargs);
3262 if (!ctx->imt_rgctx_loc)
3263 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3264 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3265 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3267 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3270 switch (cinfo->ret.storage) {
3271 case LLVMArgGsharedvtVariable: {
3272 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3274 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3275 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3277 g_assert (addresses [call->inst.dreg]);
3278 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3284 if (!addresses [call->inst.dreg])
3285 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3286 g_assert (cinfo->vret_arg_pindex < nargs);
3287 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3288 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3290 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3296 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3297 * use the real callee for argument type conversion.
3299 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3300 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3301 LLVMGetParamTypes (callee_type, param_types);
3303 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3306 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3308 pindex = ainfo->pindex;
3310 regpair = (guint32)(gssize)(l->data);
3311 reg = regpair & 0xffffff;
3312 args [pindex] = values [reg];
3313 switch (ainfo->storage) {
3314 case LLVMArgVtypeInReg:
3315 case LLVMArgAsFpArgs: {
3319 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3320 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3321 pindex += ainfo->ndummy_fpargs;
3323 g_assert (addresses [reg]);
3324 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3328 // FIXME: Get rid of the VMOVE
3331 case LLVMArgVtypeByVal:
3332 g_assert (addresses [reg]);
3333 args [pindex] = addresses [reg];
3335 case LLVMArgVtypeByRef:
3336 case LLVMArgScalarByRef: {
3337 g_assert (addresses [reg]);
3338 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3341 case LLVMArgAsIArgs:
3342 g_assert (addresses [reg]);
3343 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3345 case LLVMArgVtypeAsScalar:
3346 g_assert_not_reached ();
3348 case LLVMArgGsharedvtFixed:
3349 case LLVMArgGsharedvtFixedVtype:
3350 g_assert (addresses [reg]);
3351 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3353 case LLVMArgGsharedvtVariable:
3354 g_assert (addresses [reg]);
3355 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3358 g_assert (args [pindex]);
3359 if (i == 0 && sig->hasthis)
3360 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3362 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3365 g_assert (pindex <= nargs);
3370 // FIXME: Align call sites
3376 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3379 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3381 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3382 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3384 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3385 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3386 if (!sig->pinvoke && !cfg->llvm_only)
3387 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3389 mono_llvm_set_call_preserveall_cc (lcall);
3391 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3392 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3393 if (!ctx->llvm_only && call->rgctx_arg_reg)
3394 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3395 if (call->imt_arg_reg)
3396 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3398 /* Add byval attributes if needed */
3399 for (i = 0; i < sig->param_count; ++i) {
3400 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3402 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3403 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3407 * Convert the result
3409 switch (cinfo->ret.storage) {
3410 case LLVMArgVtypeInReg: {
3411 LLVMValueRef regs [2];
3413 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3417 if (!addresses [ins->dreg])
3418 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3420 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3421 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3422 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3423 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3426 case LLVMArgVtypeByVal:
3427 if (!addresses [call->inst.dreg])
3428 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3429 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3431 case LLVMArgFpStruct:
3432 if (!addresses [call->inst.dreg])
3433 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3434 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3436 case LLVMArgVtypeAsScalar:
3437 if (!addresses [call->inst.dreg])
3438 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3439 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3441 case LLVMArgVtypeRetAddr:
3442 case LLVMArgVtypeByRef:
3444 case LLVMArgScalarRetAddr:
3445 /* Normal scalar returned using a vtype return argument */
3446 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3448 case LLVMArgGsharedvtVariable:
3450 case LLVMArgGsharedvtFixed:
3451 case LLVMArgGsharedvtFixedVtype:
3452 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3455 if (sig->ret->type != MONO_TYPE_VOID)
3456 /* If the method returns an unsigned value, need to zext it */
3457 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));
3461 *builder_ref = ctx->builder;
3465 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3467 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3468 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3470 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3473 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3475 if (ctx->cfg->compile_aot) {
3476 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3478 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3479 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3480 mono_memory_barrier ();
3483 ctx->module->rethrow = callee;
3485 ctx->module->throw_icall = callee;
3489 LLVMValueRef args [2];
3491 args [0] = convert (ctx, exc, exc_type);
3492 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3494 LLVMBuildUnreachable (ctx->builder);
3496 ctx->builder = create_builder (ctx);
3500 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3502 MonoMethodSignature *throw_sig;
3503 LLVMValueRef callee, arg;
3504 const char *icall_name;
3506 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3507 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3510 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3511 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3512 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3513 if (ctx->cfg->compile_aot) {
3514 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3516 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3520 * LLVM doesn't push the exception argument, so we need a different
3523 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3525 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3529 mono_memory_barrier ();
3531 ctx->module->rethrow = callee;
3533 ctx->module->throw_icall = callee;
3535 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3536 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3540 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3542 const char *icall_name = "mono_llvm_resume_exception";
3543 LLVMValueRef callee = ctx->module->resume_eh;
3545 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3548 if (ctx->cfg->compile_aot) {
3549 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3551 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3552 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3553 mono_memory_barrier ();
3555 ctx->module->resume_eh = callee;
3559 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3561 LLVMBuildUnreachable (ctx->builder);
3563 ctx->builder = create_builder (ctx);
3567 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3569 const char *icall_name = "mono_llvm_clear_exception";
3571 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3572 LLVMValueRef callee = NULL;
3575 if (ctx->cfg->compile_aot) {
3576 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3578 // FIXME: This is broken.
3579 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3583 g_assert (builder && callee);
3585 return LLVMBuildCall (builder, callee, NULL, 0, "");
3589 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3591 const char *icall_name = "mono_llvm_load_exception";
3593 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3594 LLVMValueRef callee = NULL;
3597 if (ctx->cfg->compile_aot) {
3598 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3600 // FIXME: This is broken.
3601 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3605 g_assert (builder && callee);
3607 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3612 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3614 const char *icall_name = "mono_llvm_match_exception";
3616 ctx->builder = builder;
3618 const int num_args = 5;
3619 LLVMValueRef args [num_args];
3620 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3621 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3622 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3623 if (ctx->cfg->rgctx_var) {
3624 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3625 g_assert (rgctx_alloc);
3626 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3628 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3631 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3633 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3635 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3636 LLVMValueRef callee = ctx->module->match_exc;
3639 if (ctx->cfg->compile_aot) {
3640 ctx->builder = builder;
3641 // get_callee expects ctx->builder to be the emitting builder
3642 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3644 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3645 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3646 ctx->module->match_exc = callee;
3647 mono_memory_barrier ();
3651 g_assert (builder && callee);
3653 g_assert (ctx->ex_var);
3655 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3658 // FIXME: This won't work because the code-finding makes this
3660 /*#define MONO_PERSONALITY_DEBUG*/
3662 #ifdef MONO_PERSONALITY_DEBUG
3663 static const gboolean use_debug_personality = TRUE;
3664 static const char *default_personality_name = "mono_debug_personality";
3666 static const gboolean use_debug_personality = FALSE;
3667 static const char *default_personality_name = "__gxx_personality_v0";
3671 default_cpp_lpad_exc_signature (void)
3673 static gboolean inited = FALSE;
3674 static LLVMTypeRef sig;
3677 LLVMTypeRef signature [2];
3678 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3679 signature [1] = LLVMInt32Type ();
3680 sig = LLVMStructType (signature, 2, FALSE);
3688 get_mono_personality (EmitContext *ctx)
3690 LLVMValueRef personality = NULL;
3691 static gint32 mapping_inited = FALSE;
3692 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3694 if (!use_debug_personality) {
3695 if (ctx->cfg->compile_aot) {
3696 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3697 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3698 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3699 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3702 if (ctx->cfg->compile_aot) {
3703 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3705 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3706 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3707 mono_memory_barrier ();
3711 g_assert (personality);
3715 static LLVMBasicBlockRef
3716 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3718 MonoCompile *cfg = ctx->cfg;
3719 LLVMBuilderRef old_builder = ctx->builder;
3720 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3722 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3723 ctx->builder = lpadBuilder;
3725 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3726 g_assert (handler_bb);
3728 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3729 LLVMValueRef personality = get_mono_personality (ctx);
3730 g_assert (personality);
3732 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3733 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3735 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3736 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3737 g_assert (landing_pad);
3739 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3740 LLVMAddClause (landing_pad, cast);
3742 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3743 LLVMBuilderRef resume_builder = create_builder (ctx);
3744 ctx->builder = resume_builder;
3745 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3747 emit_resume_eh (ctx, handler_bb);
3750 ctx->builder = lpadBuilder;
3751 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3753 gboolean finally_only = TRUE;
3755 MonoExceptionClause *group_cursor = group_start;
3757 for (int i = 0; i < group_size; i ++) {
3758 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3759 finally_only = FALSE;
3765 // Handle landing pad inlining
3767 if (!finally_only) {
3768 // So at each level of the exception stack we will match the exception again.
3769 // During that match, we need to compare against the handler types for the current
3770 // protected region. We send the try start and end so that we can only check against
3771 // handlers for this lexical protected region.
3772 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3774 // if returns -1, resume
3775 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3777 // else move to that target bb
3778 for (int i=0; i < group_size; i++) {
3779 MonoExceptionClause *clause = group_start + i;
3780 int clause_index = clause - cfg->header->clauses;
3781 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3782 g_assert (handler_bb);
3783 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3784 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3787 int clause_index = group_start - cfg->header->clauses;
3788 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3789 g_assert (finally_bb);
3791 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3794 ctx->builder = old_builder;
3801 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3803 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3804 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3806 // Make exception available to catch blocks
3807 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3808 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3810 g_assert (ctx->ex_var);
3811 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3813 if (bb->in_scount == 1) {
3814 MonoInst *exvar = bb->in_stack [0];
3815 g_assert (!ctx->values [exvar->dreg]);
3816 g_assert (ctx->ex_var);
3817 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3818 emit_volatile_store (ctx, exvar->dreg);
3821 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3824 LLVMBuilderRef handler_builder = create_builder (ctx);
3825 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3826 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3828 // Make the handler code end with a jump to cbb
3829 LLVMBuildBr (handler_builder, cbb);
3833 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3835 MonoCompile *cfg = ctx->cfg;
3836 LLVMValueRef *values = ctx->values;
3837 LLVMModuleRef lmodule = ctx->lmodule;
3838 BBInfo *bblocks = ctx->bblocks;
3840 LLVMValueRef personality;
3841 LLVMValueRef landing_pad;
3842 LLVMBasicBlockRef target_bb;
3844 static gint32 mapping_inited;
3845 static int ti_generator;
3848 LLVMValueRef type_info;
3852 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3854 if (cfg->compile_aot) {
3855 /* Use a dummy personality function */
3856 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3857 g_assert (personality);
3859 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3860 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3861 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3864 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3866 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3869 * Create the type info
3871 sprintf (ti_name, "type_info_%d", ti_generator);
3874 if (cfg->compile_aot) {
3875 /* decode_eh_frame () in aot-runtime.c will decode this */
3876 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3877 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3880 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3882 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3885 * After the cfg mempool is freed, the type info will point to stale memory,
3886 * but this is not a problem, since we decode it once in exception_cb during
3889 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3890 *(gint32*)ti = clause_index;
3892 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3894 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3898 LLVMTypeRef members [2], ret_type;
3900 members [0] = i8ptr;
3901 members [1] = LLVMInt32Type ();
3902 ret_type = LLVMStructType (members, 2, FALSE);
3904 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3905 LLVMAddClause (landing_pad, type_info);
3907 /* Store the exception into the exvar */
3909 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3913 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3914 * code expects control to be transferred to this landing pad even in the
3915 * presence of nested clauses. The landing pad needs to branch to the landing
3916 * pads belonging to nested clauses based on the selector value returned by
3917 * the landing pad instruction, which is passed to the landing pad in a
3918 * register by the EH code.
3920 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3921 g_assert (target_bb);
3924 * Branch to the correct landing pad
3926 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3927 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3929 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3930 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3931 MonoBasicBlock *handler_bb;
3933 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3934 g_assert (handler_bb);
3936 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3937 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3940 /* Start a new bblock which CALL_HANDLER can branch to */
3941 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3943 ctx->builder = builder = create_builder (ctx);
3944 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3946 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3948 /* Store the exception into the IL level exvar */
3949 if (bb->in_scount == 1) {
3950 g_assert (bb->in_scount == 1);
3951 exvar = bb->in_stack [0];
3953 // FIXME: This is shared with filter clauses ?
3954 g_assert (!values [exvar->dreg]);
3956 g_assert (ctx->ex_var);
3957 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3958 emit_volatile_store (ctx, exvar->dreg);
3964 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3966 MonoCompile *cfg = ctx->cfg;
3967 MonoMethodSignature *sig = ctx->sig;
3968 LLVMValueRef method = ctx->lmethod;
3969 LLVMValueRef *values = ctx->values;
3970 LLVMValueRef *addresses = ctx->addresses;
3971 LLVMCallInfo *linfo = ctx->linfo;
3972 LLVMModuleRef lmodule = ctx->lmodule;
3973 BBInfo *bblocks = ctx->bblocks;
3975 LLVMBasicBlockRef cbb;
3976 LLVMBuilderRef builder, starting_builder;
3977 gboolean has_terminator;
3979 LLVMValueRef lhs, rhs;
3982 cbb = get_end_bb (ctx, bb);
3984 builder = create_builder (ctx);
3985 ctx->builder = builder;
3986 LLVMPositionBuilderAtEnd (builder, cbb);
3991 if (bb->flags & BB_EXCEPTION_HANDLER) {
3992 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3993 set_failure (ctx, "handler without invokes");
3998 emit_llvmonly_handler_start (ctx, bb, cbb);
4000 emit_handler_start (ctx, bb, builder);
4003 builder = ctx->builder;
4006 has_terminator = FALSE;
4007 starting_builder = builder;
4008 for (ins = bb->code; ins; ins = ins->next) {
4009 const char *spec = LLVM_INS_INFO (ins->opcode);
4011 char dname_buf [128];
4013 emit_dbg_loc (ctx, builder, ins->cil_code);
4018 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4019 * Start a new bblock. If the llvm optimization passes merge these, we
4020 * can work around that by doing a volatile load + cond branch from
4021 * localloc-ed memory.
4023 //set_failure (ctx, "basic block too long");
4024 cbb = gen_bb (ctx, "CONT_LONG_BB");
4025 LLVMBuildBr (ctx->builder, cbb);
4026 ctx->builder = builder = create_builder (ctx);
4027 LLVMPositionBuilderAtEnd (builder, cbb);
4028 ctx->bblocks [bb->block_num].end_bblock = cbb;
4033 /* There could be instructions after a terminator, skip them */
4036 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4037 sprintf (dname_buf, "t%d", ins->dreg);
4041 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4042 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4044 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4045 lhs = emit_volatile_load (ctx, ins->sreg1);
4047 /* It is ok for SETRET to have an uninitialized argument */
4048 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4049 set_failure (ctx, "sreg1");
4052 lhs = values [ins->sreg1];
4058 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4059 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4060 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4061 rhs = emit_volatile_load (ctx, ins->sreg2);
4063 if (!values [ins->sreg2]) {
4064 set_failure (ctx, "sreg2");
4067 rhs = values [ins->sreg2];
4073 //mono_print_ins (ins);
4074 switch (ins->opcode) {
4077 case OP_LIVERANGE_START:
4078 case OP_LIVERANGE_END:
4081 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4084 #if SIZEOF_VOID_P == 4
4085 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4087 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4091 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4095 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4097 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4099 case OP_DUMMY_ICONST:
4100 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4102 case OP_DUMMY_I8CONST:
4103 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4105 case OP_DUMMY_R8CONST:
4106 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4109 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4110 LLVMBuildBr (builder, target_bb);
4111 has_terminator = TRUE;
4118 LLVMBasicBlockRef new_bb;
4119 LLVMBuilderRef new_builder;
4121 // The default branch is already handled
4122 // FIXME: Handle it here
4124 /* Start new bblock */
4125 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4126 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4128 lhs = convert (ctx, lhs, LLVMInt32Type ());
4129 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4130 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4131 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4133 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4136 new_builder = create_builder (ctx);
4137 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4138 LLVMBuildUnreachable (new_builder);
4140 has_terminator = TRUE;
4141 g_assert (!ins->next);
4147 switch (linfo->ret.storage) {
4148 case LLVMArgVtypeInReg: {
4149 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4150 LLVMValueRef val, addr, retval;
4153 retval = LLVMGetUndef (ret_type);
4155 if (!addresses [ins->sreg1]) {
4157 * The return type is an LLVM vector type, have to convert between it and the
4158 * real return type which is a struct type.
4160 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4161 /* Convert to 2xi64 first */
4162 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4164 for (i = 0; i < 2; ++i) {
4165 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4166 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4168 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4172 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4173 for (i = 0; i < 2; ++i) {
4174 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4175 LLVMValueRef indexes [2], part_addr;
4177 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4178 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4179 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4181 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4183 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4187 LLVMBuildRet (builder, retval);
4190 case LLVMArgVtypeAsScalar: {
4191 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4192 LLVMValueRef retval;
4194 g_assert (addresses [ins->sreg1]);
4196 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4197 LLVMBuildRet (builder, retval);
4200 case LLVMArgVtypeByVal: {
4201 LLVMValueRef retval;
4203 g_assert (addresses [ins->sreg1]);
4204 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4205 LLVMBuildRet (builder, retval);
4208 case LLVMArgVtypeByRef: {
4209 LLVMBuildRetVoid (builder);
4212 case LLVMArgGsharedvtFixed: {
4213 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4214 /* The return value is in lhs, need to store to the vret argument */
4215 /* sreg1 might not be set */
4217 g_assert (cfg->vret_addr);
4218 g_assert (values [cfg->vret_addr->dreg]);
4219 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4221 LLVMBuildRetVoid (builder);
4224 case LLVMArgGsharedvtFixedVtype: {
4226 LLVMBuildRetVoid (builder);
4229 case LLVMArgGsharedvtVariable: {
4231 LLVMBuildRetVoid (builder);
4234 case LLVMArgVtypeRetAddr: {
4235 LLVMBuildRetVoid (builder);
4238 case LLVMArgScalarRetAddr: {
4239 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4240 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4242 /* sreg1 might not be set */
4244 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4245 LLVMBuildRetVoid (builder);
4248 case LLVMArgFpStruct: {
4249 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4250 LLVMValueRef retval;
4252 g_assert (addresses [ins->sreg1]);
4253 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4254 LLVMBuildRet (builder, retval);
4258 case LLVMArgNormal: {
4259 if (!lhs || ctx->is_dead [ins->sreg1]) {
4261 * The method did not set its return value, probably because it
4262 * ends with a throw.
4265 LLVMBuildRetVoid (builder);
4267 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4269 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4271 has_terminator = TRUE;
4275 g_assert_not_reached ();
4284 case OP_ICOMPARE_IMM:
4285 case OP_LCOMPARE_IMM:
4286 case OP_COMPARE_IMM: {
4288 LLVMValueRef cmp, args [16];
4289 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4291 if (ins->next->opcode == OP_NOP)
4294 if (ins->next->opcode == OP_BR)
4295 /* The comparison result is not needed */
4298 rel = mono_opcode_to_cond (ins->next->opcode);
4300 if (ins->opcode == OP_ICOMPARE_IMM) {
4301 lhs = convert (ctx, lhs, LLVMInt32Type ());
4302 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4304 if (ins->opcode == OP_LCOMPARE_IMM) {
4305 lhs = convert (ctx, lhs, LLVMInt64Type ());
4306 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4308 if (ins->opcode == OP_LCOMPARE) {
4309 lhs = convert (ctx, lhs, LLVMInt64Type ());
4310 rhs = convert (ctx, rhs, LLVMInt64Type ());
4312 if (ins->opcode == OP_ICOMPARE) {
4313 lhs = convert (ctx, lhs, LLVMInt32Type ());
4314 rhs = convert (ctx, rhs, LLVMInt32Type ());
4318 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4319 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4320 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4321 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4324 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4325 if (ins->opcode == OP_FCOMPARE) {
4326 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4327 } else if (ins->opcode == OP_RCOMPARE) {
4328 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4329 } else if (ins->opcode == OP_COMPARE_IMM) {
4330 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4331 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4333 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4334 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4335 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4336 /* The immediate is encoded in two fields */
4337 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4338 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4340 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4343 else if (ins->opcode == OP_COMPARE) {
4344 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4345 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4347 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4349 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4353 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4354 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4357 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4358 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4360 * If the target bb contains PHI instructions, LLVM requires
4361 * two PHI entries for this bblock, while we only generate one.
4362 * So convert this to an unconditional bblock. (bxc #171).
4364 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4366 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4368 has_terminator = TRUE;
4369 } else if (MONO_IS_SETCC (ins->next)) {
4370 sprintf (dname_buf, "t%d", ins->next->dreg);
4372 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4374 /* Add stores for volatile variables */
4375 emit_volatile_store (ctx, ins->next->dreg);
4376 } else if (MONO_IS_COND_EXC (ins->next)) {
4377 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4380 builder = ctx->builder;
4382 set_failure (ctx, "next");
4400 rel = mono_opcode_to_cond (ins->opcode);
4402 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4403 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4414 rel = mono_opcode_to_cond (ins->opcode);
4416 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4417 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4425 gboolean empty = TRUE;
4427 /* Check that all input bblocks really branch to us */
4428 for (i = 0; i < bb->in_count; ++i) {
4429 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4430 ins->inst_phi_args [i + 1] = -1;
4436 /* LLVM doesn't like phi instructions with zero operands */
4437 ctx->is_dead [ins->dreg] = TRUE;
4441 /* Created earlier, insert it now */
4442 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4444 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4445 int sreg1 = ins->inst_phi_args [i + 1];
4449 * Count the number of times the incoming bblock branches to us,
4450 * since llvm requires a separate entry for each.
4452 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4453 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4456 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4457 if (switch_ins->inst_many_bb [j] == bb)
4464 /* Remember for later */
4465 for (j = 0; j < count; ++j) {
4466 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4469 node->in_bb = bb->in_bb [i];
4471 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);
4481 values [ins->dreg] = lhs;
4485 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4488 values [ins->dreg] = lhs;
4490 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4492 * This is added by the spilling pass in case of the JIT,
4493 * but we have to do it ourselves.
4495 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4499 case OP_MOVE_F_TO_I4: {
4500 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4503 case OP_MOVE_I4_TO_F: {
4504 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4507 case OP_MOVE_F_TO_I8: {
4508 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4511 case OP_MOVE_I8_TO_F: {
4512 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4545 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4546 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4548 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4551 builder = ctx->builder;
4553 switch (ins->opcode) {
4556 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4560 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4564 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4568 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4572 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4576 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4580 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4584 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4588 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4592 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4596 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4600 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4604 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4608 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4612 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4615 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4618 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4622 g_assert_not_reached ();
4629 lhs = convert (ctx, lhs, LLVMFloatType ());
4630 rhs = convert (ctx, rhs, LLVMFloatType ());
4631 switch (ins->opcode) {
4633 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4636 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4639 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4642 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4645 g_assert_not_reached ();
4654 case OP_IREM_UN_IMM:
4656 case OP_IDIV_UN_IMM:
4662 case OP_ISHR_UN_IMM:
4672 case OP_LSHR_UN_IMM:
4678 case OP_SHR_UN_IMM: {
4681 if (spec [MONO_INST_SRC1] == 'l') {
4682 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4684 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4687 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4690 builder = ctx->builder;
4692 #if SIZEOF_VOID_P == 4
4693 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4694 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4697 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4698 lhs = convert (ctx, lhs, IntPtrType ());
4699 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4700 switch (ins->opcode) {
4704 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4708 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4713 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4717 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4719 case OP_IDIV_UN_IMM:
4720 case OP_LDIV_UN_IMM:
4721 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4725 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4727 case OP_IREM_UN_IMM:
4728 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4733 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4737 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4741 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4746 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4751 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4753 case OP_ISHR_UN_IMM:
4754 /* This is used to implement conv.u4, so the lhs could be an i8 */
4755 lhs = convert (ctx, lhs, LLVMInt32Type ());
4756 imm = convert (ctx, imm, LLVMInt32Type ());
4757 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4759 case OP_LSHR_UN_IMM:
4761 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4764 g_assert_not_reached ();
4769 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4772 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4775 lhs = convert (ctx, lhs, LLVMDoubleType ());
4776 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4779 lhs = convert (ctx, lhs, LLVMFloatType ());
4780 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4783 guint32 v = 0xffffffff;
4784 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4788 guint64 v = 0xffffffffffffffffLL;
4789 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4792 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4794 LLVMValueRef v1, v2;
4796 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4797 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4798 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4803 case OP_ICONV_TO_I1:
4804 case OP_ICONV_TO_I2:
4805 case OP_ICONV_TO_I4:
4806 case OP_ICONV_TO_U1:
4807 case OP_ICONV_TO_U2:
4808 case OP_ICONV_TO_U4:
4809 case OP_LCONV_TO_I1:
4810 case OP_LCONV_TO_I2:
4811 case OP_LCONV_TO_U1:
4812 case OP_LCONV_TO_U2:
4813 case OP_LCONV_TO_U4: {
4816 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);
4818 /* Have to do two casts since our vregs have type int */
4819 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4821 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4823 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4826 case OP_ICONV_TO_I8:
4827 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4829 case OP_ICONV_TO_U8:
4830 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4832 case OP_FCONV_TO_I4:
4833 case OP_RCONV_TO_I4:
4834 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4836 case OP_FCONV_TO_I1:
4837 case OP_RCONV_TO_I1:
4838 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4840 case OP_FCONV_TO_U1:
4841 case OP_RCONV_TO_U1:
4842 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4844 case OP_FCONV_TO_I2:
4845 case OP_RCONV_TO_I2:
4846 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4848 case OP_FCONV_TO_U2:
4849 case OP_RCONV_TO_U2:
4850 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4852 case OP_RCONV_TO_U4:
4853 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4855 case OP_FCONV_TO_I8:
4856 case OP_RCONV_TO_I8:
4857 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4860 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4862 case OP_ICONV_TO_R8:
4863 case OP_LCONV_TO_R8:
4864 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4866 case OP_ICONV_TO_R_UN:
4867 case OP_LCONV_TO_R_UN:
4868 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4870 #if SIZEOF_VOID_P == 4
4873 case OP_LCONV_TO_I4:
4874 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4876 case OP_ICONV_TO_R4:
4877 case OP_LCONV_TO_R4:
4878 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4880 values [ins->dreg] = v;
4882 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4884 case OP_FCONV_TO_R4:
4885 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4887 values [ins->dreg] = v;
4889 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4891 case OP_RCONV_TO_R8:
4892 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4894 case OP_RCONV_TO_R4:
4895 values [ins->dreg] = lhs;
4898 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4901 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4904 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4906 case OP_LOCALLOC_IMM: {
4909 guint32 size = ins->inst_imm;
4910 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4912 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4914 if (ins->flags & MONO_INST_INIT) {
4915 LLVMValueRef args [5];
4918 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4919 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4920 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4921 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4922 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4925 values [ins->dreg] = v;
4929 LLVMValueRef v, size;
4931 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), "");
4933 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4935 if (ins->flags & MONO_INST_INIT) {
4936 LLVMValueRef args [5];
4939 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4941 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4942 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4943 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4945 values [ins->dreg] = v;
4949 case OP_LOADI1_MEMBASE:
4950 case OP_LOADU1_MEMBASE:
4951 case OP_LOADI2_MEMBASE:
4952 case OP_LOADU2_MEMBASE:
4953 case OP_LOADI4_MEMBASE:
4954 case OP_LOADU4_MEMBASE:
4955 case OP_LOADI8_MEMBASE:
4956 case OP_LOADR4_MEMBASE:
4957 case OP_LOADR8_MEMBASE:
4958 case OP_LOAD_MEMBASE:
4966 LLVMValueRef base, index, addr;
4968 gboolean sext = FALSE, zext = FALSE;
4969 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4971 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4976 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)) {
4977 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4982 if (ins->inst_offset == 0) {
4984 } else if (ins->inst_offset % size != 0) {
4985 /* Unaligned load */
4986 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4987 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4989 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4990 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4994 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4996 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4998 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5000 * These will signal LLVM that these loads do not alias any stores, and
5001 * they can't fail, allowing them to be hoisted out of loops.
5003 set_invariant_load_flag (values [ins->dreg]);
5004 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5008 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5010 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5011 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5012 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5016 case OP_STOREI1_MEMBASE_REG:
5017 case OP_STOREI2_MEMBASE_REG:
5018 case OP_STOREI4_MEMBASE_REG:
5019 case OP_STOREI8_MEMBASE_REG:
5020 case OP_STORER4_MEMBASE_REG:
5021 case OP_STORER8_MEMBASE_REG:
5022 case OP_STORE_MEMBASE_REG: {
5024 LLVMValueRef index, addr;
5026 gboolean sext = FALSE, zext = FALSE;
5027 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5029 if (!values [ins->inst_destbasereg]) {
5030 set_failure (ctx, "inst_destbasereg");
5034 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5036 if (ins->inst_offset % size != 0) {
5037 /* Unaligned store */
5038 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5039 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5041 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5042 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5044 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5048 case OP_STOREI1_MEMBASE_IMM:
5049 case OP_STOREI2_MEMBASE_IMM:
5050 case OP_STOREI4_MEMBASE_IMM:
5051 case OP_STOREI8_MEMBASE_IMM:
5052 case OP_STORE_MEMBASE_IMM: {
5054 LLVMValueRef index, addr;
5056 gboolean sext = FALSE, zext = FALSE;
5057 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5059 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5061 if (ins->inst_offset % size != 0) {
5062 /* Unaligned store */
5063 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5064 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5066 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5067 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5069 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5074 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5076 case OP_OUTARG_VTRETADDR:
5084 case OP_VOIDCALL_MEMBASE:
5085 case OP_CALL_MEMBASE:
5086 case OP_LCALL_MEMBASE:
5087 case OP_FCALL_MEMBASE:
5088 case OP_RCALL_MEMBASE:
5089 case OP_VCALL_MEMBASE:
5090 case OP_VOIDCALL_REG:
5095 case OP_VCALL_REG: {
5096 process_call (ctx, bb, &builder, ins);
5101 LLVMValueRef indexes [2];
5102 MonoJumpInfo *tmp_ji, *ji;
5103 LLVMValueRef got_entry_addr;
5107 * FIXME: Can't allocate from the cfg mempool since that is freed if
5108 * the LLVM compile fails.
5110 tmp_ji = g_new0 (MonoJumpInfo, 1);
5111 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5112 tmp_ji->data.target = ins->inst_p0;
5114 ji = mono_aot_patch_info_dup (tmp_ji);
5117 ji->next = cfg->patch_info;
5118 cfg->patch_info = ji;
5120 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5121 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5122 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5123 if (!mono_aot_is_shared_got_offset (got_offset)) {
5124 //mono_print_ji (ji);
5126 ctx->has_got_access = TRUE;
5129 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5130 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5131 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5133 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5134 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5136 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5137 if (!cfg->llvm_only)
5138 set_invariant_load_flag (values [ins->dreg]);
5141 case OP_NOT_REACHED:
5142 LLVMBuildUnreachable (builder);
5143 has_terminator = TRUE;
5144 g_assert (bb->block_num < cfg->max_block_num);
5145 ctx->unreachable [bb->block_num] = TRUE;
5146 /* Might have instructions after this */
5148 MonoInst *next = ins->next;
5150 * FIXME: If later code uses the regs defined by these instructions,
5151 * compilation will fail.
5153 MONO_DELETE_INS (bb, next);
5157 MonoInst *var = ins->inst_i0;
5159 if (var->opcode == OP_VTARG_ADDR) {
5160 /* The variable contains the vtype address */
5161 values [ins->dreg] = values [var->dreg];
5162 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5163 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5165 values [ins->dreg] = addresses [var->dreg];
5170 LLVMValueRef args [1];
5172 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5173 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5177 LLVMValueRef args [1];
5179 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5180 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5184 LLVMValueRef args [1];
5186 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5187 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5191 LLVMValueRef args [1];
5193 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5194 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5208 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5209 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5211 switch (ins->opcode) {
5214 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5218 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5222 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5226 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5229 g_assert_not_reached ();
5232 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5235 case OP_ATOMIC_EXCHANGE_I4:
5236 case OP_ATOMIC_EXCHANGE_I8: {
5237 LLVMValueRef args [2];
5240 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5241 t = LLVMInt32Type ();
5243 t = LLVMInt64Type ();
5245 g_assert (ins->inst_offset == 0);
5247 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5248 args [1] = convert (ctx, rhs, t);
5250 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5253 case OP_ATOMIC_ADD_I4:
5254 case OP_ATOMIC_ADD_I8: {
5255 LLVMValueRef args [2];
5258 if (ins->opcode == OP_ATOMIC_ADD_I4)
5259 t = LLVMInt32Type ();
5261 t = LLVMInt64Type ();
5263 g_assert (ins->inst_offset == 0);
5265 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5266 args [1] = convert (ctx, rhs, t);
5267 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5270 case OP_ATOMIC_CAS_I4:
5271 case OP_ATOMIC_CAS_I8: {
5272 LLVMValueRef args [3], val;
5275 if (ins->opcode == OP_ATOMIC_CAS_I4)
5276 t = LLVMInt32Type ();
5278 t = LLVMInt64Type ();
5280 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5282 args [1] = convert (ctx, values [ins->sreg3], t);
5284 args [2] = convert (ctx, values [ins->sreg2], t);
5285 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5286 /* cmpxchg returns a pair */
5287 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5290 case OP_MEMORY_BARRIER: {
5291 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5294 case OP_ATOMIC_LOAD_I1:
5295 case OP_ATOMIC_LOAD_I2:
5296 case OP_ATOMIC_LOAD_I4:
5297 case OP_ATOMIC_LOAD_I8:
5298 case OP_ATOMIC_LOAD_U1:
5299 case OP_ATOMIC_LOAD_U2:
5300 case OP_ATOMIC_LOAD_U4:
5301 case OP_ATOMIC_LOAD_U8:
5302 case OP_ATOMIC_LOAD_R4:
5303 case OP_ATOMIC_LOAD_R8: {
5304 set_failure (ctx, "atomic mono.load intrinsic");
5308 gboolean sext, zext;
5310 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5311 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5312 LLVMValueRef index, addr;
5314 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5319 if (ins->inst_offset != 0) {
5320 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5321 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5326 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5328 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5331 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5333 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5337 case OP_ATOMIC_STORE_I1:
5338 case OP_ATOMIC_STORE_I2:
5339 case OP_ATOMIC_STORE_I4:
5340 case OP_ATOMIC_STORE_I8:
5341 case OP_ATOMIC_STORE_U1:
5342 case OP_ATOMIC_STORE_U2:
5343 case OP_ATOMIC_STORE_U4:
5344 case OP_ATOMIC_STORE_U8:
5345 case OP_ATOMIC_STORE_R4:
5346 case OP_ATOMIC_STORE_R8: {
5347 set_failure (ctx, "atomic mono.store intrinsic");
5351 gboolean sext, zext;
5353 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5354 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5355 LLVMValueRef index, addr, value;
5357 if (!values [ins->inst_destbasereg]) {
5358 set_failure (ctx, "inst_destbasereg");
5362 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5364 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5365 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5366 value = convert (ctx, values [ins->sreg1], t);
5368 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5372 case OP_RELAXED_NOP: {
5373 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5374 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5381 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5383 // 257 == FS segment register
5384 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5386 // 256 == GS segment register
5387 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5390 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5391 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5392 /* See mono_amd64_emit_tls_get () */
5393 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5395 // 256 == GS segment register
5396 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5397 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5399 set_failure (ctx, "opcode tls-get");
5405 case OP_TLS_GET_REG: {
5406 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5407 /* See emit_tls_get_reg () */
5408 // 256 == GS segment register
5409 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5410 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5412 set_failure (ctx, "opcode tls-get");
5418 case OP_TLS_SET_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 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5425 set_failure (ctx, "opcode tls-set-reg");
5435 case OP_IADD_OVF_UN:
5437 case OP_ISUB_OVF_UN:
5439 case OP_IMUL_OVF_UN:
5440 #if SIZEOF_VOID_P == 8
5442 case OP_LADD_OVF_UN:
5444 case OP_LSUB_OVF_UN:
5446 case OP_LMUL_OVF_UN:
5449 LLVMValueRef args [2], val, ovf, func;
5451 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5452 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5453 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5455 val = LLVMBuildCall (builder, func, args, 2, "");
5456 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5457 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5458 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5461 builder = ctx->builder;
5467 * We currently model them using arrays. Promotion to local vregs is
5468 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5469 * so we always have an entry in cfg->varinfo for them.
5470 * FIXME: Is this needed ?
5473 MonoClass *klass = ins->klass;
5474 LLVMValueRef args [5];
5478 set_failure (ctx, "!klass");
5482 if (!addresses [ins->dreg])
5483 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5484 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5485 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5486 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5488 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5489 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5490 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5493 case OP_DUMMY_VZERO:
5496 case OP_STOREV_MEMBASE:
5497 case OP_LOADV_MEMBASE:
5499 MonoClass *klass = ins->klass;
5500 LLVMValueRef src = NULL, dst, args [5];
5501 gboolean done = FALSE;
5505 set_failure (ctx, "!klass");
5509 if (mini_is_gsharedvt_klass (klass)) {
5511 set_failure (ctx, "gsharedvt");
5515 switch (ins->opcode) {
5516 case OP_STOREV_MEMBASE:
5517 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5518 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5519 /* Decomposed earlier */
5520 g_assert_not_reached ();
5523 if (!addresses [ins->sreg1]) {
5525 g_assert (values [ins->sreg1]);
5526 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));
5527 LLVMBuildStore (builder, values [ins->sreg1], dst);
5530 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5531 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5534 case OP_LOADV_MEMBASE:
5535 if (!addresses [ins->dreg])
5536 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5537 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5538 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5541 if (!addresses [ins->sreg1])
5542 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5543 if (!addresses [ins->dreg])
5544 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5545 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5546 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5549 g_assert_not_reached ();
5559 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5560 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5562 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5563 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5564 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5567 case OP_LLVM_OUTARG_VT: {
5568 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5569 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5571 if (ainfo->storage == LLVMArgScalarByRef) {
5572 LLVMTypeRef argtype;
5573 LLVMValueRef loc, v;
5575 argtype = type_to_llvm_arg_type (ctx, t);
5576 loc = build_alloca_llvm_type (ctx, argtype, 0);
5577 v = convert (ctx, values [ins->sreg1], argtype);
5578 LLVMBuildStore (ctx->builder, v, loc);
5579 addresses [ins->dreg] = loc;
5580 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5581 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5583 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5584 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5586 g_assert (addresses [ins->sreg1]);
5587 addresses [ins->dreg] = addresses [ins->sreg1];
5589 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5590 if (!addresses [ins->sreg1]) {
5591 addresses [ins->sreg1] = build_alloca (ctx, t);
5592 g_assert (values [ins->sreg1]);
5594 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5595 addresses [ins->dreg] = addresses [ins->sreg1];
5597 if (!addresses [ins->sreg1]) {
5598 addresses [ins->sreg1] = build_alloca (ctx, t);
5599 g_assert (values [ins->sreg1]);
5600 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5602 addresses [ins->dreg] = addresses [ins->sreg1];
5610 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5612 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5615 case OP_LOADX_MEMBASE: {
5616 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5619 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5620 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5623 case OP_STOREX_MEMBASE: {
5624 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5627 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5628 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5635 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5639 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5645 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5649 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5653 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5657 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5660 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5663 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5666 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5670 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5681 LLVMValueRef v = NULL;
5683 switch (ins->opcode) {
5688 t = LLVMVectorType (LLVMInt32Type (), 4);
5689 rt = LLVMVectorType (LLVMFloatType (), 4);
5695 t = LLVMVectorType (LLVMInt64Type (), 2);
5696 rt = LLVMVectorType (LLVMDoubleType (), 2);
5699 t = LLVMInt32Type ();
5700 rt = LLVMInt32Type ();
5701 g_assert_not_reached ();
5704 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5705 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5706 switch (ins->opcode) {
5709 v = LLVMBuildAnd (builder, lhs, rhs, "");
5713 v = LLVMBuildOr (builder, lhs, rhs, "");
5717 v = LLVMBuildXor (builder, lhs, rhs, "");
5721 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5724 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5748 case OP_PADDB_SAT_UN:
5749 case OP_PADDW_SAT_UN:
5750 case OP_PSUBB_SAT_UN:
5751 case OP_PSUBW_SAT_UN:
5759 case OP_PMULW_HIGH_UN: {
5760 LLVMValueRef args [2];
5765 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5772 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5776 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5784 case OP_EXTRACTX_U2:
5786 case OP_EXTRACT_U1: {
5788 gboolean zext = FALSE;
5790 t = simd_op_to_llvm_type (ins->opcode);
5792 switch (ins->opcode) {
5800 case OP_EXTRACTX_U2:
5805 t = LLVMInt32Type ();
5806 g_assert_not_reached ();
5809 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5810 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5812 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5821 case OP_EXPAND_R8: {
5822 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5823 LLVMValueRef mask [16], v;
5826 for (i = 0; i < 16; ++i)
5827 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5829 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5831 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5832 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5837 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5840 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5843 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5846 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5849 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5852 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5863 case OP_EXTRACT_MASK:
5870 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5872 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5878 LLVMValueRef args [3];
5882 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5884 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5889 /* This is only used for implementing shifts by non-immediate */
5890 values [ins->dreg] = lhs;
5901 LLVMValueRef args [3];
5904 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5906 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5917 case OP_PSHLQ_REG: {
5918 LLVMValueRef args [3];
5921 args [1] = values [ins->sreg2];
5923 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5930 case OP_PSHUFLEW_LOW:
5931 case OP_PSHUFLEW_HIGH: {
5933 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5934 int i, mask_size = 0;
5935 int imask = ins->inst_c0;
5937 /* Convert the x86 shuffle mask to LLVM's */
5938 switch (ins->opcode) {
5941 mask [0] = ((imask >> 0) & 3);
5942 mask [1] = ((imask >> 2) & 3);
5943 mask [2] = ((imask >> 4) & 3) + 4;
5944 mask [3] = ((imask >> 6) & 3) + 4;
5945 v1 = values [ins->sreg1];
5946 v2 = values [ins->sreg2];
5950 mask [0] = ((imask >> 0) & 1);
5951 mask [1] = ((imask >> 1) & 1) + 2;
5952 v1 = values [ins->sreg1];
5953 v2 = values [ins->sreg2];
5955 case OP_PSHUFLEW_LOW:
5957 mask [0] = ((imask >> 0) & 3);
5958 mask [1] = ((imask >> 2) & 3);
5959 mask [2] = ((imask >> 4) & 3);
5960 mask [3] = ((imask >> 6) & 3);
5965 v1 = values [ins->sreg1];
5966 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5968 case OP_PSHUFLEW_HIGH:
5974 mask [4] = 4 + ((imask >> 0) & 3);
5975 mask [5] = 4 + ((imask >> 2) & 3);
5976 mask [6] = 4 + ((imask >> 4) & 3);
5977 mask [7] = 4 + ((imask >> 6) & 3);
5978 v1 = values [ins->sreg1];
5979 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5983 mask [0] = ((imask >> 0) & 3);
5984 mask [1] = ((imask >> 2) & 3);
5985 mask [2] = ((imask >> 4) & 3);
5986 mask [3] = ((imask >> 6) & 3);
5987 v1 = values [ins->sreg1];
5988 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5991 g_assert_not_reached ();
5993 for (i = 0; i < mask_size; ++i)
5994 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5996 values [ins->dreg] =
5997 LLVMBuildShuffleVector (builder, v1, v2,
5998 LLVMConstVector (mask_values, mask_size), dname);
6002 case OP_UNPACK_LOWB:
6003 case OP_UNPACK_LOWW:
6004 case OP_UNPACK_LOWD:
6005 case OP_UNPACK_LOWQ:
6006 case OP_UNPACK_LOWPS:
6007 case OP_UNPACK_LOWPD:
6008 case OP_UNPACK_HIGHB:
6009 case OP_UNPACK_HIGHW:
6010 case OP_UNPACK_HIGHD:
6011 case OP_UNPACK_HIGHQ:
6012 case OP_UNPACK_HIGHPS:
6013 case OP_UNPACK_HIGHPD: {
6015 LLVMValueRef mask_values [16];
6016 int i, mask_size = 0;
6017 gboolean low = FALSE;
6019 switch (ins->opcode) {
6020 case OP_UNPACK_LOWB:
6024 case OP_UNPACK_LOWW:
6028 case OP_UNPACK_LOWD:
6029 case OP_UNPACK_LOWPS:
6033 case OP_UNPACK_LOWQ:
6034 case OP_UNPACK_LOWPD:
6038 case OP_UNPACK_HIGHB:
6041 case OP_UNPACK_HIGHW:
6044 case OP_UNPACK_HIGHD:
6045 case OP_UNPACK_HIGHPS:
6048 case OP_UNPACK_HIGHQ:
6049 case OP_UNPACK_HIGHPD:
6053 g_assert_not_reached ();
6057 for (i = 0; i < (mask_size / 2); ++i) {
6059 mask [(i * 2) + 1] = mask_size + i;
6062 for (i = 0; i < (mask_size / 2); ++i) {
6063 mask [(i * 2)] = (mask_size / 2) + i;
6064 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6068 for (i = 0; i < mask_size; ++i)
6069 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6071 values [ins->dreg] =
6072 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6073 LLVMConstVector (mask_values, mask_size), dname);
6078 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6079 LLVMValueRef v, val;
6081 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6082 val = LLVMConstNull (t);
6083 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6084 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6086 values [ins->dreg] = val;
6090 case OP_DUPPS_HIGH: {
6091 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6092 LLVMValueRef v1, v2, val;
6095 if (ins->opcode == OP_DUPPS_LOW) {
6096 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6097 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6099 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6100 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6102 val = LLVMConstNull (t);
6103 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6104 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6105 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6106 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6108 values [ins->dreg] = val;
6118 * EXCEPTION HANDLING
6120 case OP_IMPLICIT_EXCEPTION:
6121 /* This marks a place where an implicit exception can happen */
6122 if (bb->region != -1)
6123 set_failure (ctx, "implicit-exception");
6127 gboolean rethrow = (ins->opcode == OP_RETHROW);
6128 if (ctx->llvm_only) {
6129 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6130 has_terminator = TRUE;
6131 ctx->unreachable [bb->block_num] = TRUE;
6133 emit_throw (ctx, bb, rethrow, lhs);
6134 builder = ctx->builder;
6138 case OP_CALL_HANDLER: {
6140 * We don't 'call' handlers, but instead simply branch to them.
6141 * The code generated by ENDFINALLY will branch back to us.
6143 LLVMBasicBlockRef noex_bb;
6145 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6147 bb_list = info->call_handler_return_bbs;
6150 * Set the indicator variable for the finally clause.
6152 lhs = info->finally_ind;
6154 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6156 /* Branch to the finally clause */
6157 LLVMBuildBr (builder, info->call_handler_target_bb);
6159 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6160 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6162 builder = ctx->builder = create_builder (ctx);
6163 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6165 bblocks [bb->block_num].end_bblock = noex_bb;
6168 case OP_START_HANDLER: {
6171 case OP_ENDFINALLY: {
6172 LLVMBasicBlockRef resume_bb;
6173 MonoBasicBlock *handler_bb;
6174 LLVMValueRef val, switch_ins, callee;
6178 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6179 g_assert (handler_bb);
6180 info = &bblocks [handler_bb->block_num];
6181 lhs = info->finally_ind;
6184 bb_list = info->call_handler_return_bbs;
6186 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6188 /* Load the finally variable */
6189 val = LLVMBuildLoad (builder, lhs, "");
6191 /* Reset the variable */
6192 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6194 /* Branch to either resume_bb, or to the bblocks in bb_list */
6195 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6197 * The other targets are added at the end to handle OP_CALL_HANDLER
6198 * opcodes processed later.
6200 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6202 builder = ctx->builder = create_builder (ctx);
6203 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6205 if (ctx->llvm_only) {
6206 emit_resume_eh (ctx, bb);
6208 if (ctx->cfg->compile_aot) {
6209 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6211 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6213 LLVMBuildCall (builder, callee, NULL, 0, "");
6214 LLVMBuildUnreachable (builder);
6217 has_terminator = TRUE;
6220 case OP_IL_SEQ_POINT:
6225 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6226 set_failure (ctx, reason);
6234 /* Convert the value to the type required by phi nodes */
6235 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6236 if (!values [ins->dreg])
6238 values [ins->dreg] = addresses [ins->dreg];
6240 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6243 /* Add stores for volatile variables */
6244 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6245 emit_volatile_store (ctx, ins->dreg);
6251 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6252 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6255 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6256 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6257 LLVMBuildRetVoid (builder);
6260 if (bb == cfg->bb_entry)
6261 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6265 * mono_llvm_check_method_supported:
6267 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6268 * compiling a method twice.
6271 mono_llvm_check_method_supported (MonoCompile *cfg)
6278 if (cfg->method->save_lmf) {
6279 cfg->exception_message = g_strdup ("lmf");
6280 cfg->disable_llvm = TRUE;
6282 if (cfg->disable_llvm)
6286 * Nested clauses where one of the clauses is a finally clause is
6287 * not supported, because LLVM can't figure out the control flow,
6288 * probably because we resume exception handling by calling our
6289 * own function instead of using the 'resume' llvm instruction.
6291 for (i = 0; i < cfg->header->num_clauses; ++i) {
6292 for (j = 0; j < cfg->header->num_clauses; ++j) {
6293 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6294 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6296 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6297 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6298 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6299 cfg->exception_message = g_strdup ("nested clauses");
6300 cfg->disable_llvm = TRUE;
6305 if (cfg->disable_llvm)
6309 if (cfg->method->dynamic) {
6310 cfg->exception_message = g_strdup ("dynamic.");
6311 cfg->disable_llvm = TRUE;
6313 if (cfg->disable_llvm)
6317 static LLVMCallInfo*
6318 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6320 LLVMCallInfo *linfo;
6323 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6327 * Gsharedvt methods have the following calling convention:
6328 * - all arguments are passed by ref, even non generic ones
6329 * - the return value is returned by ref too, using a vret
6330 * argument passed after 'this'.
6332 n = sig->param_count + sig->hasthis;
6333 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6337 linfo->args [pindex ++].storage = LLVMArgNormal;
6339 if (sig->ret->type != MONO_TYPE_VOID) {
6340 if (mini_is_gsharedvt_variable_type (sig->ret))
6341 linfo->ret.storage = LLVMArgGsharedvtVariable;
6342 else if (mini_type_is_vtype (sig->ret))
6343 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6345 linfo->ret.storage = LLVMArgGsharedvtFixed;
6346 linfo->vret_arg_index = pindex;
6348 linfo->ret.storage = LLVMArgNone;
6351 for (i = 0; i < sig->param_count; ++i) {
6352 if (sig->params [i]->byref)
6353 linfo->args [pindex].storage = LLVMArgNormal;
6354 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6355 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6356 else if (mini_type_is_vtype (sig->params [i]))
6357 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6359 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6360 linfo->args [pindex].type = sig->params [i];
6367 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6368 for (i = 0; i < sig->param_count; ++i)
6369 linfo->args [i + sig->hasthis].type = sig->params [i];
6375 emit_method_inner (EmitContext *ctx);
6378 free_ctx (EmitContext *ctx)
6382 g_free (ctx->values);
6383 g_free (ctx->addresses);
6384 g_free (ctx->vreg_types);
6385 g_free (ctx->vreg_cli_types);
6386 g_free (ctx->is_dead);
6387 g_free (ctx->unreachable);
6388 g_ptr_array_free (ctx->phi_values, TRUE);
6389 g_free (ctx->bblocks);
6390 g_hash_table_destroy (ctx->region_to_handler);
6391 g_hash_table_destroy (ctx->clause_to_handler);
6392 g_free (ctx->method_name);
6393 g_ptr_array_free (ctx->bblock_list, TRUE);
6395 for (l = ctx->builders; l; l = l->next) {
6396 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6397 LLVMDisposeBuilder (builder);
6404 * mono_llvm_emit_method:
6406 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6409 mono_llvm_emit_method (MonoCompile *cfg)
6413 gboolean is_linkonce = FALSE;
6416 /* The code below might acquire the loader lock, so use it for global locking */
6417 mono_loader_lock ();
6419 /* Used to communicate with the callbacks */
6420 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6422 ctx = g_new0 (EmitContext, 1);
6424 ctx->mempool = cfg->mempool;
6427 * This maps vregs to the LLVM instruction defining them
6429 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6431 * This maps vregs for volatile variables to the LLVM instruction defining their
6434 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6435 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6436 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6437 ctx->phi_values = g_ptr_array_sized_new (256);
6439 * This signals whenever the vreg was defined by a phi node with no input vars
6440 * (i.e. all its input bblocks end with NOT_REACHABLE).
6442 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6443 /* Whenever the bblock is unreachable */
6444 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6445 ctx->bblock_list = g_ptr_array_sized_new (256);
6447 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6448 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6449 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6450 if (cfg->compile_aot) {
6451 ctx->module = &aot_module;
6455 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6456 * linkage for them. This requires the following:
6457 * - the method needs to have a unique mangled name
6458 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6460 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6462 method_name = mono_aot_get_mangled_method_name (cfg->method);
6464 is_linkonce = FALSE;
6467 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6469 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6473 method_name = mono_aot_get_method_name (cfg);
6474 cfg->llvm_method_name = g_strdup (method_name);
6476 init_jit_module (cfg->domain);
6477 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6478 method_name = mono_method_full_name (cfg->method, TRUE);
6480 ctx->method_name = method_name;
6481 ctx->is_linkonce = is_linkonce;
6483 ctx->lmodule = ctx->module->lmodule;
6484 ctx->llvm_only = ctx->module->llvm_only;
6486 emit_method_inner (ctx);
6488 if (!ctx_ok (ctx)) {
6490 /* Need to add unused phi nodes as they can be referenced by other values */
6491 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6492 LLVMBuilderRef builder;
6494 builder = create_builder (ctx);
6495 LLVMPositionBuilderAtEnd (builder, phi_bb);
6497 for (i = 0; i < ctx->phi_values->len; ++i) {
6498 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6499 if (LLVMGetInstructionParent (v) == NULL)
6500 LLVMInsertIntoBuilder (builder, v);
6503 LLVMDeleteFunction (ctx->lmethod);
6509 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6511 mono_loader_unlock ();
6515 emit_method_inner (EmitContext *ctx)
6517 MonoCompile *cfg = ctx->cfg;
6518 MonoMethodSignature *sig;
6520 LLVMTypeRef method_type;
6521 LLVMValueRef method = NULL;
6522 LLVMValueRef *values = ctx->values;
6523 int i, max_block_num, bb_index;
6524 gboolean last = FALSE;
6525 LLVMCallInfo *linfo;
6526 LLVMModuleRef lmodule = ctx->lmodule;
6528 GPtrArray *bblock_list = ctx->bblock_list;
6529 MonoMethodHeader *header;
6530 MonoExceptionClause *clause;
6533 if (cfg->gsharedvt && !cfg->llvm_only) {
6534 set_failure (ctx, "gsharedvt");
6540 static int count = 0;
6543 if (g_getenv ("LLVM_COUNT")) {
6544 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6545 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6549 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6550 set_failure (ctx, "count");
6557 sig = mono_method_signature (cfg->method);
6560 linfo = get_llvm_call_info (cfg, sig);
6566 linfo->rgctx_arg = TRUE;
6567 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6571 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6572 ctx->lmethod = method;
6574 if (!cfg->llvm_only)
6575 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6576 LLVMSetLinkage (method, LLVMPrivateLinkage);
6578 LLVMAddFunctionAttr (method, LLVMUWTable);
6580 if (cfg->compile_aot) {
6581 LLVMSetLinkage (method, LLVMInternalLinkage);
6582 if (ctx->module->external_symbols) {
6583 LLVMSetLinkage (method, LLVMExternalLinkage);
6584 LLVMSetVisibility (method, LLVMHiddenVisibility);
6586 if (ctx->is_linkonce) {
6587 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6588 LLVMSetVisibility (method, LLVMDefaultVisibility);
6591 LLVMSetLinkage (method, LLVMPrivateLinkage);
6594 if (cfg->method->save_lmf && !cfg->llvm_only) {
6595 set_failure (ctx, "lmf");
6599 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6600 set_failure (ctx, "pinvoke signature");
6604 header = cfg->header;
6605 for (i = 0; i < header->num_clauses; ++i) {
6606 clause = &header->clauses [i];
6607 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6608 set_failure (ctx, "non-finally/catch clause.");
6612 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6613 /* We can't handle inlined methods with clauses */
6614 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6616 if (linfo->rgctx_arg) {
6617 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6618 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6620 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6621 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6622 * CC_X86_64_Mono in X86CallingConv.td.
6624 if (!ctx->llvm_only)
6625 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6626 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6628 ctx->rgctx_arg_pindex = -1;
6630 if (cfg->vret_addr) {
6631 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6632 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6633 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6634 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6635 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6637 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6638 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6639 LLVMSetValueName (param, "vret");
6643 ctx->this_arg_pindex = linfo->this_arg_pindex;
6644 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6645 values [cfg->args [0]->dreg] = ctx->this_arg;
6646 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6649 names = g_new (char *, sig->param_count);
6650 mono_method_get_param_names (cfg->method, (const char **) names);
6652 for (i = 0; i < sig->param_count; ++i) {
6653 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6655 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6658 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6659 name = g_strdup_printf ("dummy_%d_%d", i, j);
6660 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6664 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6665 if (ainfo->storage == LLVMArgScalarByRef) {
6666 if (names [i] && names [i][0] != '\0')
6667 name = g_strdup_printf ("p_arg_%s", names [i]);
6669 name = g_strdup_printf ("p_arg_%d", i);
6670 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6671 if (names [i] && names [i][0] != '\0')
6672 name = g_strdup_printf ("p_arg_%s", names [i]);
6674 name = g_strdup_printf ("p_arg_%d", i);
6676 if (names [i] && names [i][0] != '\0')
6677 name = g_strdup_printf ("arg_%s", names [i]);
6679 name = g_strdup_printf ("arg_%d", i);
6681 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6683 if (ainfo->storage == LLVMArgVtypeByVal)
6684 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6686 if (ainfo->storage == LLVMArgVtypeByRef) {
6688 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6693 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6694 ctx->minfo = mono_debug_lookup_method (cfg->method);
6695 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6699 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6700 max_block_num = MAX (max_block_num, bb->block_num);
6701 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6703 /* Add branches between non-consecutive bblocks */
6704 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6705 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6706 bb->next_bb != bb->last_ins->inst_false_bb) {
6708 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6709 inst->opcode = OP_BR;
6710 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6711 mono_bblock_add_inst (bb, inst);
6716 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6717 * was later optimized away, so clear these flags, and add them back for the still
6718 * present OP_LDADDR instructions.
6720 for (i = 0; i < cfg->next_vreg; ++i) {
6723 ins = get_vreg_to_inst (cfg, i);
6724 if (ins && ins != cfg->rgctx_var)
6725 ins->flags &= ~MONO_INST_INDIRECT;
6729 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6731 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6733 LLVMBuilderRef builder;
6735 char dname_buf[128];
6737 builder = create_builder (ctx);
6739 for (ins = bb->code; ins; ins = ins->next) {
6740 switch (ins->opcode) {
6745 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6750 if (ins->opcode == OP_VPHI) {
6751 /* Treat valuetype PHI nodes as operating on the address itself */
6752 g_assert (ins->klass);
6753 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6757 * Have to precreate these, as they can be referenced by
6758 * earlier instructions.
6760 sprintf (dname_buf, "t%d", ins->dreg);
6762 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6764 if (ins->opcode == OP_VPHI)
6765 ctx->addresses [ins->dreg] = values [ins->dreg];
6767 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6770 * Set the expected type of the incoming arguments since these have
6771 * to have the same type.
6773 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6774 int sreg1 = ins->inst_phi_args [i + 1];
6777 ctx->vreg_types [sreg1] = phi_type;
6782 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6791 * Create an ordering for bblocks, use the depth first order first, then
6792 * put the exception handling bblocks last.
6794 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6795 bb = cfg->bblocks [bb_index];
6796 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6797 g_ptr_array_add (bblock_list, bb);
6798 bblocks [bb->block_num].added = TRUE;
6802 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6803 if (!bblocks [bb->block_num].added)
6804 g_ptr_array_add (bblock_list, bb);
6808 * Second pass: generate code.
6811 LLVMBuilderRef entry_builder = create_builder (ctx);
6812 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6813 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6814 emit_entry_bb (ctx, entry_builder);
6816 // Make landing pads first
6817 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6819 if (ctx->llvm_only) {
6820 size_t group_index = 0;
6821 while (group_index < cfg->header->num_clauses) {
6823 size_t cursor = group_index;
6824 while (cursor < cfg->header->num_clauses &&
6825 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6826 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6831 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6832 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6833 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6835 group_index = cursor;
6839 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6840 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6842 // Prune unreachable mono BBs.
6843 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6846 process_bb (ctx, bb);
6850 g_hash_table_destroy (ctx->exc_meta);
6852 mono_memory_barrier ();
6854 /* Add incoming phi values */
6855 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6856 GSList *l, *ins_list;
6858 ins_list = bblocks [bb->block_num].phi_nodes;
6860 for (l = ins_list; l; l = l->next) {
6861 PhiNode *node = (PhiNode*)l->data;
6862 MonoInst *phi = node->phi;
6863 int sreg1 = node->sreg;
6864 LLVMBasicBlockRef in_bb;
6869 in_bb = get_end_bb (ctx, node->in_bb);
6871 if (ctx->unreachable [node->in_bb->block_num])
6874 if (!values [sreg1]) {
6875 /* Can happen with values in EH clauses */
6876 set_failure (ctx, "incoming phi sreg1");
6880 if (phi->opcode == OP_VPHI) {
6881 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6882 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6884 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6885 set_failure (ctx, "incoming phi arg type mismatch");
6888 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6889 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6894 /* Nullify empty phi instructions */
6895 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6896 GSList *l, *ins_list;
6898 ins_list = bblocks [bb->block_num].phi_nodes;
6900 for (l = ins_list; l; l = l->next) {
6901 PhiNode *node = (PhiNode*)l->data;
6902 MonoInst *phi = node->phi;
6903 LLVMValueRef phi_ins = values [phi->dreg];
6906 /* Already removed */
6909 if (LLVMCountIncoming (phi_ins) == 0) {
6910 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6911 LLVMInstructionEraseFromParent (phi_ins);
6912 values [phi->dreg] = NULL;
6917 /* Create the SWITCH statements for ENDFINALLY instructions */
6918 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6919 BBInfo *info = &bblocks [bb->block_num];
6921 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6922 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6923 GSList *bb_list = info->call_handler_return_bbs;
6925 for (i = 0; i < g_slist_length (bb_list); ++i)
6926 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6930 /* Initialize the method if needed */
6931 if (cfg->compile_aot && ctx->llvm_only) {
6932 // FIXME: Add more shared got entries
6933 ctx->builder = create_builder (ctx);
6934 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6936 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6938 // FIXME: beforefieldinit
6939 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6940 emit_init_method (ctx);
6942 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6946 if (cfg->llvm_only) {
6947 GHashTableIter iter;
6949 GSList *callers, *l, *l2;
6952 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6953 * We can't do this earlier, as it contains llvm instructions which can be
6954 * freed if compilation fails.
6955 * FIXME: Get rid of this when all methods can be llvm compiled.
6957 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6958 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6959 for (l = callers; l; l = l->next) {
6960 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6961 l2 = g_slist_prepend (l2, l->data);
6962 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6967 if (cfg->verbose_level > 1)
6968 mono_llvm_dump_value (method);
6970 if (cfg->compile_aot && !cfg->llvm_only)
6971 mark_as_used (ctx->module, method);
6973 if (cfg->compile_aot && !cfg->llvm_only) {
6974 LLVMValueRef md_args [16];
6975 LLVMValueRef md_node;
6978 method_index = mono_aot_get_method_index (cfg->orig_method);
6979 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6980 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6981 md_node = LLVMMDNode (md_args, 2);
6982 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6983 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6986 if (cfg->compile_aot) {
6987 /* Don't generate native code, keep the LLVM IR */
6988 if (cfg->verbose_level)
6989 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
6991 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
6992 g_assert (err == 0);
6994 //LLVMVerifyFunction(method, 0);
6995 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
6997 if (cfg->verbose_level > 1)
6998 mono_llvm_dump_value (ctx->lmethod);
7000 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7002 /* Set by emit_cb */
7003 g_assert (cfg->code_len);
7006 if (ctx->module->method_to_lmethod)
7007 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7008 if (ctx->module->idx_to_lmethod)
7009 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7011 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7012 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7016 * mono_llvm_create_vars:
7018 * Same as mono_arch_create_vars () for LLVM.
7021 mono_llvm_create_vars (MonoCompile *cfg)
7023 MonoMethodSignature *sig;
7025 sig = mono_method_signature (cfg->method);
7026 if (cfg->gsharedvt && cfg->llvm_only) {
7027 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7028 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7029 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7030 printf ("vret_addr = ");
7031 mono_print_ins (cfg->vret_addr);
7035 mono_arch_create_vars (cfg);
7040 * mono_llvm_emit_call:
7042 * Same as mono_arch_emit_call () for LLVM.
7045 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7048 MonoMethodSignature *sig;
7049 int i, n, stack_size;
7054 sig = call->signature;
7055 n = sig->param_count + sig->hasthis;
7057 call->cinfo = get_llvm_call_info (cfg, sig);
7059 if (cfg->disable_llvm)
7062 if (sig->call_convention == MONO_CALL_VARARG) {
7063 cfg->exception_message = g_strdup ("varargs");
7064 cfg->disable_llvm = TRUE;
7067 for (i = 0; i < n; ++i) {
7070 ainfo = call->cinfo->args + i;
7072 in = call->args [i];
7074 /* Simply remember the arguments */
7075 switch (ainfo->storage) {
7076 case LLVMArgNormal: {
7077 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7080 opcode = mono_type_to_regmove (cfg, t);
7081 if (opcode == OP_FMOVE) {
7082 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7083 ins->dreg = mono_alloc_freg (cfg);
7084 } else if (opcode == OP_LMOVE) {
7085 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7086 ins->dreg = mono_alloc_lreg (cfg);
7087 } else if (opcode == OP_RMOVE) {
7088 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7089 ins->dreg = mono_alloc_freg (cfg);
7091 MONO_INST_NEW (cfg, ins, OP_MOVE);
7092 ins->dreg = mono_alloc_ireg (cfg);
7094 ins->sreg1 = in->dreg;
7097 case LLVMArgVtypeByVal:
7098 case LLVMArgVtypeByRef:
7099 case LLVMArgVtypeInReg:
7100 case LLVMArgVtypeAsScalar:
7101 case LLVMArgScalarByRef:
7102 case LLVMArgAsIArgs:
7103 case LLVMArgAsFpArgs:
7104 case LLVMArgGsharedvtVariable:
7105 case LLVMArgGsharedvtFixed:
7106 case LLVMArgGsharedvtFixedVtype:
7107 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7108 ins->dreg = mono_alloc_ireg (cfg);
7109 ins->sreg1 = in->dreg;
7110 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7111 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7112 ins->inst_vtype = ainfo->type;
7113 ins->klass = mono_class_from_mono_type (ainfo->type);
7116 cfg->exception_message = g_strdup ("ainfo->storage");
7117 cfg->disable_llvm = TRUE;
7121 if (!cfg->disable_llvm) {
7122 MONO_ADD_INS (cfg->cbb, ins);
7123 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7128 static unsigned char*
7129 alloc_cb (LLVMValueRef function, int size)
7133 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7137 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7139 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7144 emitted_cb (LLVMValueRef function, void *start, void *end)
7148 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7150 cfg->code_len = (guint8*)end - (guint8*)start;
7154 exception_cb (void *data)
7157 MonoJitExceptionInfo *ei;
7158 guint32 ei_len, i, j, nested_len, nindex;
7159 gpointer *type_info;
7160 int this_reg, this_offset;
7162 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7166 * data points to a DWARF FDE structure, convert it to our unwind format and
7168 * An alternative would be to save it directly, and modify our unwinder to work
7171 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);
7172 if (cfg->verbose_level > 1)
7173 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7175 /* Count nested clauses */
7177 for (i = 0; i < ei_len; ++i) {
7178 gint32 cindex1 = *(gint32*)type_info [i];
7179 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7181 for (j = 0; j < cfg->header->num_clauses; ++j) {
7183 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7185 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7191 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7192 cfg->llvm_ex_info_len = ei_len + nested_len;
7193 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7194 /* Fill the rest of the information from the type info */
7195 for (i = 0; i < ei_len; ++i) {
7196 gint32 clause_index = *(gint32*)type_info [i];
7197 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7199 cfg->llvm_ex_info [i].flags = clause->flags;
7200 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7201 cfg->llvm_ex_info [i].clause_index = clause_index;
7205 * For nested clauses, the LLVM produced exception info associates the try interval with
7206 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7207 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7208 * and everything else from the nested clause.
7211 for (i = 0; i < ei_len; ++i) {
7212 gint32 cindex1 = *(gint32*)type_info [i];
7213 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7215 for (j = 0; j < cfg->header->num_clauses; ++j) {
7217 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7218 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7220 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7221 /* clause1 is the nested clause */
7222 nested_ei = &cfg->llvm_ex_info [i];
7223 nesting_ei = &cfg->llvm_ex_info [nindex];
7226 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7228 nesting_ei->flags = clause2->flags;
7229 nesting_ei->data.catch_class = clause2->data.catch_class;
7230 nesting_ei->clause_index = cindex2;
7234 g_assert (nindex == ei_len + nested_len);
7235 cfg->llvm_this_reg = this_reg;
7236 cfg->llvm_this_offset = this_offset;
7238 /* type_info [i] is cfg mempool allocated, no need to free it */
7245 dlsym_cb (const char *name, void **symbol)
7251 if (!strcmp (name, "__bzero")) {
7252 *symbol = (void*)bzero;
7254 current = mono_dl_open (NULL, 0, NULL);
7257 err = mono_dl_symbol (current, name, symbol);
7259 mono_dl_close (current);
7261 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7262 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7268 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7270 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7274 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7276 LLVMTypeRef param_types [4];
7278 param_types [0] = param_type1;
7279 param_types [1] = param_type2;
7281 AddFunc (module, name, ret_type, param_types, 2);
7285 add_intrinsics (LLVMModuleRef module)
7287 /* Emit declarations of instrinsics */
7289 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7290 * type doesn't seem to do any locking.
7293 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7295 memset_param_count = 5;
7296 memset_func_name = "llvm.memset.p0i8.i32";
7298 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7302 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7304 memcpy_param_count = 5;
7305 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7307 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7311 LLVMTypeRef params [] = { LLVMDoubleType () };
7313 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7314 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7315 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7317 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7318 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7322 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7323 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7324 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7326 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7327 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7328 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7329 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7330 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7331 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7332 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7336 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7337 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7338 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7340 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7341 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7342 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7343 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7344 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7345 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7348 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7349 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7353 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7355 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7358 /* SSE intrinsics */
7359 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7361 LLVMTypeRef ret_type, arg_types [16];
7364 ret_type = type_to_simd_type (MONO_TYPE_I4);
7365 arg_types [0] = ret_type;
7366 arg_types [1] = ret_type;
7367 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7368 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7370 ret_type = type_to_simd_type (MONO_TYPE_I2);
7371 arg_types [0] = ret_type;
7372 arg_types [1] = ret_type;
7373 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7374 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7375 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7376 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7377 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7378 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7379 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7380 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7382 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7384 ret_type = type_to_simd_type (MONO_TYPE_I1);
7385 arg_types [0] = ret_type;
7386 arg_types [1] = ret_type;
7387 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7388 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7389 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7390 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7391 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7392 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7395 ret_type = type_to_simd_type (MONO_TYPE_R8);
7396 arg_types [0] = ret_type;
7397 arg_types [1] = ret_type;
7398 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7399 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7400 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7401 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7402 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7404 ret_type = type_to_simd_type (MONO_TYPE_R4);
7405 arg_types [0] = ret_type;
7406 arg_types [1] = ret_type;
7407 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7408 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7409 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7410 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7411 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7414 ret_type = type_to_simd_type (MONO_TYPE_I1);
7415 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7416 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7417 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7418 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7419 ret_type = type_to_simd_type (MONO_TYPE_I2);
7420 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7421 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7422 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7423 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7426 ret_type = type_to_simd_type (MONO_TYPE_R8);
7427 arg_types [0] = ret_type;
7428 arg_types [1] = ret_type;
7429 arg_types [2] = LLVMInt8Type ();
7430 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7431 ret_type = type_to_simd_type (MONO_TYPE_R4);
7432 arg_types [0] = ret_type;
7433 arg_types [1] = ret_type;
7434 arg_types [2] = LLVMInt8Type ();
7435 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7437 /* Conversion ops */
7438 ret_type = type_to_simd_type (MONO_TYPE_R8);
7439 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7440 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7441 ret_type = type_to_simd_type (MONO_TYPE_R4);
7442 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7443 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7444 ret_type = type_to_simd_type (MONO_TYPE_I4);
7445 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7446 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7447 ret_type = type_to_simd_type (MONO_TYPE_I4);
7448 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7449 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7450 ret_type = type_to_simd_type (MONO_TYPE_R4);
7451 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7452 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7453 ret_type = type_to_simd_type (MONO_TYPE_R8);
7454 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7455 AddFunc (module, "llvm.x86.sse2.cvtps2pd", 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.cvttpd2dq", 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.cvttps2dq", ret_type, arg_types, 1);
7465 ret_type = type_to_simd_type (MONO_TYPE_R8);
7466 arg_types [0] = ret_type;
7467 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7468 ret_type = type_to_simd_type (MONO_TYPE_R4);
7469 arg_types [0] = ret_type;
7470 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7471 ret_type = type_to_simd_type (MONO_TYPE_R4);
7472 arg_types [0] = ret_type;
7473 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7474 ret_type = type_to_simd_type (MONO_TYPE_R4);
7475 arg_types [0] = ret_type;
7476 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7479 ret_type = type_to_simd_type (MONO_TYPE_I2);
7480 arg_types [0] = ret_type;
7481 arg_types [1] = LLVMInt32Type ();
7482 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7483 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7484 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7485 ret_type = type_to_simd_type (MONO_TYPE_I4);
7486 arg_types [0] = ret_type;
7487 arg_types [1] = LLVMInt32Type ();
7488 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7489 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7490 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7491 ret_type = type_to_simd_type (MONO_TYPE_I8);
7492 arg_types [0] = ret_type;
7493 arg_types [1] = LLVMInt32Type ();
7494 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7495 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7498 ret_type = LLVMInt32Type ();
7499 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7500 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7503 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7506 /* Load/Store intrinsics */
7508 LLVMTypeRef arg_types [5];
7512 for (i = 1; i <= 8; i *= 2) {
7513 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7514 arg_types [1] = LLVMInt32Type ();
7515 arg_types [2] = LLVMInt1Type ();
7516 arg_types [3] = LLVMInt32Type ();
7517 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7518 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7520 arg_types [0] = LLVMIntType (i * 8);
7521 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7522 arg_types [2] = LLVMInt32Type ();
7523 arg_types [3] = LLVMInt1Type ();
7524 arg_types [4] = LLVMInt32Type ();
7525 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7526 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7532 add_types (MonoLLVMModule *module)
7534 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7538 mono_llvm_init (void)
7540 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7544 init_jit_module (MonoDomain *domain)
7546 MonoJitICallInfo *info;
7547 MonoJitDomainInfo *dinfo;
7548 MonoLLVMModule *module;
7551 dinfo = domain_jit_info (domain);
7552 if (dinfo->llvm_module)
7555 mono_loader_lock ();
7557 if (dinfo->llvm_module) {
7558 mono_loader_unlock ();
7562 module = g_new0 (MonoLLVMModule, 1);
7564 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7565 module->lmodule = LLVMModuleCreateWithName (name);
7566 module->context = LLVMGetGlobalContext ();
7568 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7570 add_intrinsics (module->lmodule);
7573 module->llvm_types = g_hash_table_new (NULL, NULL);
7575 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7577 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7579 mono_memory_barrier ();
7581 dinfo->llvm_module = module;
7583 mono_loader_unlock ();
7587 mono_llvm_cleanup (void)
7589 MonoLLVMModule *module = &aot_module;
7591 if (module->lmodule)
7592 LLVMDisposeModule (module->lmodule);
7594 if (module->context)
7595 LLVMContextDispose (module->context);
7599 mono_llvm_free_domain_info (MonoDomain *domain)
7601 MonoJitDomainInfo *info = domain_jit_info (domain);
7602 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7608 if (module->llvm_types)
7609 g_hash_table_destroy (module->llvm_types);
7611 mono_llvm_dispose_ee (module->mono_ee);
7613 if (module->bb_names) {
7614 for (i = 0; i < module->bb_names_len; ++i)
7615 g_free (module->bb_names [i]);
7616 g_free (module->bb_names);
7618 //LLVMDisposeModule (module->module);
7622 info->llvm_module = NULL;
7626 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7628 MonoLLVMModule *module = &aot_module;
7630 /* Delete previous module */
7631 if (module->plt_entries)
7632 g_hash_table_destroy (module->plt_entries);
7633 if (module->lmodule)
7634 LLVMDisposeModule (module->lmodule);
7636 memset (module, 0, sizeof (aot_module));
7638 module->lmodule = LLVMModuleCreateWithName ("aot");
7639 module->assembly = assembly;
7640 module->global_prefix = g_strdup (global_prefix);
7641 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7642 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7643 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7644 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7645 module->external_symbols = TRUE;
7646 module->emit_dwarf = emit_dwarf;
7647 module->static_link = static_link;
7648 module->llvm_only = llvm_only;
7649 /* The first few entries are reserved */
7650 module->max_got_offset = 16;
7651 module->context = LLVMContextCreate ();
7654 /* clang ignores our debug info because it has an invalid version */
7655 module->emit_dwarf = FALSE;
7657 add_intrinsics (module->lmodule);
7662 * We couldn't compute the type of the LLVM global representing the got because
7663 * its size is only known after all the methods have been emitted. So create
7664 * a dummy variable, and replace all uses it with the real got variable when
7665 * its size is known in mono_llvm_emit_aot_module ().
7668 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7670 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7671 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7674 /* Add initialization array */
7676 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7678 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7679 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7683 emit_init_icall_wrappers (module);
7685 emit_llvm_code_start (module);
7687 /* Add a dummy personality function */
7688 if (!use_debug_personality) {
7689 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7690 LLVMSetLinkage (personality, LLVMExternalLinkage);
7691 mark_as_used (module, personality);
7694 /* Add a reference to the c++ exception we throw/catch */
7696 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7697 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7698 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7699 mono_llvm_set_is_constant (module->sentinel_exception);
7702 module->llvm_types = g_hash_table_new (NULL, NULL);
7703 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7704 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7705 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7706 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7707 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7708 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7709 module->method_to_callers = g_hash_table_new (NULL, NULL);
7713 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7716 LLVMValueRef res, *vals;
7718 vals = g_new0 (LLVMValueRef, nvalues);
7719 for (i = 0; i < nvalues; ++i)
7720 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7721 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7727 * mono_llvm_emit_aot_file_info:
7729 * Emit the MonoAotFileInfo structure.
7730 * Same as emit_aot_file_info () in aot-compiler.c.
7733 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7735 MonoLLVMModule *module = &aot_module;
7737 /* Save these for later */
7738 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7739 module->has_jitted_code = has_jitted_code;
7743 * mono_llvm_emit_aot_data:
7745 * Emit the binary data DATA pointed to by symbol SYMBOL.
7748 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7750 MonoLLVMModule *module = &aot_module;
7754 type = LLVMArrayType (LLVMInt8Type (), data_len);
7755 d = LLVMAddGlobal (module->lmodule, type, symbol);
7756 LLVMSetVisibility (d, LLVMHiddenVisibility);
7757 LLVMSetLinkage (d, LLVMInternalLinkage);
7758 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7759 mono_llvm_set_is_constant (d);
7762 /* Add a reference to a global defined in JITted code */
7764 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7769 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7770 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7776 emit_aot_file_info (MonoLLVMModule *module)
7778 LLVMTypeRef file_info_type;
7779 LLVMTypeRef *eltypes, eltype;
7780 LLVMValueRef info_var;
7781 LLVMValueRef *fields;
7782 int i, nfields, tindex;
7783 MonoAotFileInfo *info;
7784 LLVMModuleRef lmodule = module->lmodule;
7786 info = &module->aot_info;
7788 /* Create an LLVM type to represent MonoAotFileInfo */
7789 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7790 eltypes = g_new (LLVMTypeRef, nfields);
7792 eltypes [tindex ++] = LLVMInt32Type ();
7793 eltypes [tindex ++] = LLVMInt32Type ();
7795 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7796 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7798 for (i = 0; i < 15; ++i)
7799 eltypes [tindex ++] = LLVMInt32Type ();
7801 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7802 for (i = 0; i < 4; ++i)
7803 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7804 g_assert (tindex == nfields);
7805 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7806 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7808 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7809 if (module->static_link) {
7810 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7811 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7813 fields = g_new (LLVMValueRef, nfields);
7815 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7816 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7820 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7821 * for symbols defined in the .s file emitted by the aot compiler.
7823 eltype = eltypes [tindex];
7824 if (module->llvm_only)
7825 fields [tindex ++] = LLVMConstNull (eltype);
7827 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7828 fields [tindex ++] = module->got_var;
7829 /* llc defines this directly */
7830 if (!module->llvm_only) {
7831 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7832 fields [tindex ++] = LLVMConstNull (eltype);
7833 fields [tindex ++] = LLVMConstNull (eltype);
7835 fields [tindex ++] = LLVMConstNull (eltype);
7836 fields [tindex ++] = module->get_method;
7837 fields [tindex ++] = module->get_unbox_tramp;
7839 if (module->has_jitted_code) {
7840 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7841 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7843 fields [tindex ++] = LLVMConstNull (eltype);
7844 fields [tindex ++] = LLVMConstNull (eltype);
7846 if (!module->llvm_only)
7847 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7849 fields [tindex ++] = LLVMConstNull (eltype);
7850 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7851 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7852 fields [tindex ++] = LLVMConstNull (eltype);
7854 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7855 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7856 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7857 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7858 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7859 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7860 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7861 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7862 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7863 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7865 /* Not needed (mem_end) */
7866 fields [tindex ++] = LLVMConstNull (eltype);
7867 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7868 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7869 if (info->trampoline_size [0]) {
7870 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7871 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7872 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7873 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7875 fields [tindex ++] = LLVMConstNull (eltype);
7876 fields [tindex ++] = LLVMConstNull (eltype);
7877 fields [tindex ++] = LLVMConstNull (eltype);
7878 fields [tindex ++] = LLVMConstNull (eltype);
7880 if (module->static_link && !module->llvm_only)
7881 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7883 fields [tindex ++] = LLVMConstNull (eltype);
7884 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7885 if (!module->llvm_only) {
7886 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7887 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7888 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7889 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7890 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7891 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7893 fields [tindex ++] = LLVMConstNull (eltype);
7894 fields [tindex ++] = LLVMConstNull (eltype);
7895 fields [tindex ++] = LLVMConstNull (eltype);
7896 fields [tindex ++] = LLVMConstNull (eltype);
7897 fields [tindex ++] = LLVMConstNull (eltype);
7898 fields [tindex ++] = LLVMConstNull (eltype);
7901 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7902 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7905 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7906 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7907 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7908 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7909 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7910 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7911 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7912 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7913 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7914 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7915 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7916 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7917 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7918 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7919 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7921 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7922 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7923 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7924 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7925 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7926 g_assert (tindex == nfields);
7928 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7930 if (module->static_link) {
7934 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7935 /* Get rid of characters which cannot occur in symbols */
7937 for (p = s; *p; ++p) {
7938 if (!(isalnum (*p) || *p == '_'))
7941 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7943 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7944 LLVMSetLinkage (var, LLVMExternalLinkage);
7949 * Emit the aot module into the LLVM bitcode file FILENAME.
7952 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7954 LLVMTypeRef got_type, inited_type;
7955 LLVMValueRef real_got, real_inited;
7956 MonoLLVMModule *module = &aot_module;
7958 emit_llvm_code_end (module);
7961 * Create the real got variable and replace all uses of the dummy variable with
7964 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7965 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7966 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7967 if (module->external_symbols) {
7968 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7969 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7971 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7973 mono_llvm_replace_uses_of (module->got_var, real_got);
7975 mark_as_used (&aot_module, real_got);
7977 /* Delete the dummy got so it doesn't become a global */
7978 LLVMDeleteGlobal (module->got_var);
7979 module->got_var = real_got;
7982 * Same for the init_var
7984 if (module->llvm_only) {
7985 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7986 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7987 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7988 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7989 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7990 LLVMDeleteGlobal (module->inited_var);
7993 if (module->llvm_only) {
7994 emit_get_method (&aot_module);
7995 emit_get_unbox_tramp (&aot_module);
7998 emit_llvm_used (&aot_module);
7999 emit_dbg_info (&aot_module, filename, cu_name);
8000 emit_aot_file_info (&aot_module);
8002 mono_llvm_create_di_compile_unit (aot_module.lmodule);
8005 * Replace GOT entries for directly callable methods with the methods themselves.
8006 * It would be easier to implement this by predefining all methods before compiling
8007 * their bodies, but that couldn't handle the case when a method fails to compile
8010 if (module->llvm_only) {
8011 GHashTableIter iter;
8013 GSList *callers, *l;
8015 g_hash_table_iter_init (&iter, module->method_to_callers);
8016 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8017 LLVMValueRef lmethod;
8019 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8021 for (l = callers; l; l = l->next) {
8022 LLVMValueRef caller = (LLVMValueRef)l->data;
8024 mono_llvm_replace_uses_of (caller, lmethod);
8030 /* Replace PLT entries for directly callable methods with the methods themselves */
8032 GHashTableIter iter;
8034 LLVMValueRef callee;
8036 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8037 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8038 if (mono_aot_is_direct_callable (ji)) {
8039 LLVMValueRef lmethod;
8041 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8042 /* The types might not match because the caller might pass an rgctx */
8043 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8044 mono_llvm_replace_uses_of (callee, lmethod);
8045 mono_aot_mark_unused_llvm_plt_entry (ji);
8055 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
8056 g_assert_not_reached ();
8061 LLVMWriteBitcodeToFile (module->lmodule, filename);
8066 md_string (const char *s)
8068 return LLVMMDString (s, strlen (s));
8071 /* Debugging support */
8074 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8076 LLVMModuleRef lmodule = module->lmodule;
8077 LLVMValueRef args [16], cu_args [16], cu, ver;
8079 char *build_info, *s, *dir;
8082 * This can only be enabled when LLVM code is emitted into a separate object
8083 * file, since the AOT compiler also emits dwarf info,
8084 * and the abbrev indexes will not be correct since llvm has added its own
8087 if (!module->emit_dwarf)
8091 * Emit dwarf info in the form of LLVM metadata. There is some
8092 * out-of-date documentation at:
8093 * http://llvm.org/docs/SourceLevelDebugging.html
8094 * but most of this was gathered from the llvm and
8099 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8100 /* CU name/compilation dir */
8101 dir = g_path_get_dirname (filename);
8102 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8103 args [1] = LLVMMDString (dir, strlen (dir));
8104 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8107 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8109 build_info = mono_get_runtime_build_info ();
8110 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8111 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8112 g_free (build_info);
8114 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8116 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8117 /* Runtime version */
8118 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8120 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8121 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8123 if (module->subprogram_mds) {
8127 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8128 for (i = 0; i < module->subprogram_mds->len; ++i)
8129 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8130 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8132 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8135 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8136 /* Imported modules */
8137 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8139 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8140 /* DebugEmissionKind = FullDebug */
8141 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8142 cu = LLVMMDNode (cu_args, n_cuargs);
8143 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8145 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8146 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8147 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8148 ver = LLVMMDNode (args, 3);
8149 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8151 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8152 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8153 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8154 ver = LLVMMDNode (args, 3);
8155 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8159 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8161 MonoLLVMModule *module = ctx->module;
8162 MonoDebugMethodInfo *minfo = ctx->minfo;
8163 char *source_file, *dir, *filename;
8164 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8165 MonoSymSeqPoint *sym_seq_points;
8171 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8173 source_file = g_strdup ("<unknown>");
8174 dir = g_path_get_dirname (source_file);
8175 filename = g_path_get_basename (source_file);
8177 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8178 args [0] = md_string (filename);
8179 args [1] = md_string (dir);
8180 ctx_args [1] = LLVMMDNode (args, 2);
8181 ctx_md = LLVMMDNode (ctx_args, 2);
8183 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8184 type_args [1] = NULL;
8185 type_args [2] = NULL;
8186 type_args [3] = LLVMMDString ("", 0);
8187 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8188 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8189 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8190 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8191 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8192 type_args [9] = NULL;
8193 type_args [10] = NULL;
8194 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8195 type_args [12] = NULL;
8196 type_args [13] = NULL;
8197 type_args [14] = NULL;
8198 type_md = LLVMMDNode (type_args, 14);
8200 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8201 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8202 /* Source directory + file pair */
8203 args [0] = md_string (filename);
8204 args [1] = md_string (dir);
8205 md_args [1] = LLVMMDNode (args ,2);
8206 md_args [2] = ctx_md;
8207 md_args [3] = md_string (cfg->method->name);
8208 md_args [4] = md_string (name);
8209 md_args [5] = md_string (name);
8212 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8214 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8216 md_args [7] = type_md;
8218 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8220 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8222 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8223 /* Index into a virtual function */
8224 md_args [11] = NULL;
8225 md_args [12] = NULL;
8227 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8229 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8230 /* Pointer to LLVM function */
8231 md_args [15] = method;
8232 /* Function template parameter */
8233 md_args [16] = NULL;
8234 /* Function declaration descriptor */
8235 md_args [17] = NULL;
8236 /* List of function variables */
8237 md_args [18] = LLVMMDNode (args, 0);
8239 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8240 md = LLVMMDNode (md_args, 20);
8242 if (!module->subprogram_mds)
8243 module->subprogram_mds = g_ptr_array_new ();
8244 g_ptr_array_add (module->subprogram_mds, md);
8248 g_free (source_file);
8249 g_free (sym_seq_points);
8255 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8257 MonoCompile *cfg = ctx->cfg;
8259 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8260 MonoDebugSourceLocation *loc;
8261 LLVMValueRef loc_md, md_args [16];
8264 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8268 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8269 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8270 md_args [nmd_args ++] = ctx->dbg_md;
8271 md_args [nmd_args ++] = NULL;
8272 loc_md = LLVMMDNode (md_args, nmd_args);
8273 LLVMSetCurrentDebugLocation (builder, loc_md);
8274 mono_debug_symfile_free_location (loc);
8280 default_mono_llvm_unhandled_exception (void)
8282 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8283 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8285 mono_unhandled_exception (target);
8286 exit (mono_environment_exitcode_get ());
8291 - Emit LLVM IR from the mono IR using the LLVM C API.
8292 - The original arch specific code remains, so we can fall back to it if we run
8293 into something we can't handle.
8297 A partial list of issues:
8298 - Handling of opcodes which can throw exceptions.
8300 In the mono JIT, these are implemented using code like this:
8307 push throw_pos - method
8308 call <exception trampoline>
8310 The problematic part is push throw_pos - method, which cannot be represented
8311 in the LLVM IR, since it does not support label values.
8312 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8313 be implemented in JIT mode ?
8314 -> a possible but slower implementation would use the normal exception
8315 throwing code but it would need to control the placement of the throw code
8316 (it needs to be exactly after the compare+branch).
8317 -> perhaps add a PC offset intrinsics ?
8319 - efficient implementation of .ovf opcodes.
8321 These are currently implemented as:
8322 <ins which sets the condition codes>
8325 Some overflow opcodes are now supported by LLVM SVN.
8327 - exception handling, unwinding.
8328 - SSA is disabled for methods with exception handlers
8329 - How to obtain unwind info for LLVM compiled methods ?
8330 -> this is now solved by converting the unwind info generated by LLVM
8332 - LLVM uses the c++ exception handling framework, while we use our home grown
8333 code, and couldn't use the c++ one:
8334 - its not supported under VC++, other exotic platforms.
8335 - it might be impossible to support filter clauses with it.
8339 The trampolines need a predictable call sequence, since they need to disasm
8340 the calling code to obtain register numbers / offsets.
8342 LLVM currently generates this code in non-JIT mode:
8343 mov -0x98(%rax),%eax
8345 Here, the vtable pointer is lost.
8346 -> solution: use one vtable trampoline per class.
8348 - passing/receiving the IMT pointer/RGCTX.
8349 -> solution: pass them as normal arguments ?
8353 LLVM does not allow the specification of argument registers etc. This means
8354 that all calls are made according to the platform ABI.
8356 - passing/receiving vtypes.
8358 Vtypes passed/received in registers are handled by the front end by using
8359 a signature with scalar arguments, and loading the parts of the vtype into those
8362 Vtypes passed on the stack are handled using the 'byval' attribute.
8366 Supported though alloca, we need to emit the load/store code.
8370 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8371 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8372 This is made easier because the IR is already in SSA form.
8373 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8374 types are frequently used incorrectly.
8379 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8380 it with the file containing the methods emitted by the JIT and the AOT data
8384 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8385 * - each bblock should end with a branch
8386 * - setting the return value, making cfg->ret non-volatile
8387 * - avoid some transformations in the JIT which make it harder for us to generate
8389 * - use pointer types to help optimizations.