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);
268 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
271 set_failure (EmitContext *ctx, const char *message)
273 TRACE_FAILURE (reason);
274 ctx->cfg->exception_message = g_strdup (message);
275 ctx->cfg->disable_llvm = TRUE;
281 * The LLVM type with width == sizeof (gpointer)
286 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
292 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 * Return the size of the LLVM representation of the vtype T.
307 get_vtype_size (MonoType *t)
311 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
313 /* LLVMArgAsIArgs depends on this since it stores whole words */
314 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
321 * simd_class_to_llvm_type:
323 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
326 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
328 if (!strcmp (klass->name, "Vector2d")) {
329 return LLVMVectorType (LLVMDoubleType (), 2);
330 } else if (!strcmp (klass->name, "Vector2l")) {
331 return LLVMVectorType (LLVMInt64Type (), 2);
332 } else if (!strcmp (klass->name, "Vector2ul")) {
333 return LLVMVectorType (LLVMInt64Type (), 2);
334 } else if (!strcmp (klass->name, "Vector4i")) {
335 return LLVMVectorType (LLVMInt32Type (), 4);
336 } else if (!strcmp (klass->name, "Vector4ui")) {
337 return LLVMVectorType (LLVMInt32Type (), 4);
338 } else if (!strcmp (klass->name, "Vector4f")) {
339 return LLVMVectorType (LLVMFloatType (), 4);
340 } else if (!strcmp (klass->name, "Vector8s")) {
341 return LLVMVectorType (LLVMInt16Type (), 8);
342 } else if (!strcmp (klass->name, "Vector8us")) {
343 return LLVMVectorType (LLVMInt16Type (), 8);
344 } else if (!strcmp (klass->name, "Vector16sb")) {
345 return LLVMVectorType (LLVMInt8Type (), 16);
346 } else if (!strcmp (klass->name, "Vector16b")) {
347 return LLVMVectorType (LLVMInt8Type (), 16);
349 printf ("%s\n", klass->name);
355 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
356 static inline G_GNUC_UNUSED LLVMTypeRef
357 type_to_simd_type (int type)
361 return LLVMVectorType (LLVMInt8Type (), 16);
363 return LLVMVectorType (LLVMInt16Type (), 8);
365 return LLVMVectorType (LLVMInt32Type (), 4);
367 return LLVMVectorType (LLVMInt64Type (), 2);
369 return LLVMVectorType (LLVMDoubleType (), 2);
371 return LLVMVectorType (LLVMFloatType (), 4);
373 g_assert_not_reached ();
379 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
381 int i, size, nfields, esize;
382 LLVMTypeRef *eltypes;
387 t = &klass->byval_arg;
389 if (mini_type_is_hfa (t, &nfields, &esize)) {
391 * This is needed on arm64 where HFAs are returned in
395 eltypes = g_new (LLVMTypeRef, size);
396 for (i = 0; i < size; ++i)
397 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
399 size = get_vtype_size (t);
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = LLVMInt8Type ();
406 name = mono_type_full_name (&klass->byval_arg);
407 ltype = LLVMStructCreateNamed (module->context, name);
408 LLVMStructSetBody (ltype, eltypes, size, FALSE);
418 * Return the LLVM type corresponding to T.
421 type_to_llvm_type (EmitContext *ctx, MonoType *t)
423 t = mini_get_underlying_type (t);
427 return LLVMVoidType ();
429 return LLVMInt8Type ();
431 return LLVMInt16Type ();
433 return LLVMInt32Type ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
440 case MONO_TYPE_BOOLEAN:
441 return LLVMInt8Type ();
444 return LLVMInt64Type ();
446 return LLVMInt16Type ();
448 return LLVMFloatType ();
450 return LLVMDoubleType ();
453 return IntPtrType ();
454 case MONO_TYPE_OBJECT:
455 case MONO_TYPE_CLASS:
456 case MONO_TYPE_ARRAY:
457 case MONO_TYPE_SZARRAY:
458 case MONO_TYPE_STRING:
460 return ObjRefType ();
463 /* Because of generic sharing */
464 return ObjRefType ();
465 case MONO_TYPE_GENERICINST:
466 if (!mono_type_generic_inst_is_valuetype (t))
467 return ObjRefType ();
469 case MONO_TYPE_VALUETYPE:
470 case MONO_TYPE_TYPEDBYREF: {
474 klass = mono_class_from_mono_type (t);
476 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
477 return simd_class_to_llvm_type (ctx, klass);
480 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
482 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
484 ltype = create_llvm_type_for_type (ctx->module, klass);
485 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
491 printf ("X: %d\n", t->type);
492 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
493 ctx->cfg->disable_llvm = TRUE;
501 * Return whenever T is an unsigned int type.
504 type_is_unsigned (EmitContext *ctx, MonoType *t)
506 t = mini_get_underlying_type (t);
522 * type_to_llvm_arg_type:
524 * Same as type_to_llvm_type, but treat i8/i16 as i32.
527 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
529 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
531 if (ctx->cfg->llvm_only)
535 * This works on all abis except arm64/ios which passes multiple
536 * arguments in one stack slot.
539 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
541 * LLVM generates code which only sets the lower bits, while JITted
542 * code expects all the bits to be set.
544 ptype = LLVMInt32Type ();
552 * llvm_type_to_stack_type:
554 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
557 static G_GNUC_UNUSED LLVMTypeRef
558 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
562 if (type == LLVMInt8Type ())
563 return LLVMInt32Type ();
564 else if (type == LLVMInt16Type ())
565 return LLVMInt32Type ();
566 else if (!cfg->r4fp && type == LLVMFloatType ())
567 return LLVMDoubleType ();
573 * regtype_to_llvm_type:
575 * Return the LLVM type corresponding to the regtype C used in instruction
579 regtype_to_llvm_type (char c)
583 return LLVMInt32Type ();
585 return LLVMInt64Type ();
587 return LLVMDoubleType ();
596 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
599 op_to_llvm_type (int opcode)
604 return LLVMInt8Type ();
607 return LLVMInt8Type ();
610 return LLVMInt16Type ();
613 return LLVMInt16Type ();
616 return LLVMInt32Type ();
619 return LLVMInt32Type ();
621 return LLVMInt64Type ();
623 return LLVMFloatType ();
625 return LLVMDoubleType ();
627 return LLVMInt64Type ();
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
636 return LLVMInt8Type ();
641 return LLVMInt16Type ();
643 return LLVMInt32Type ();
646 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
653 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 printf ("%s\n", mono_inst_name (opcode));
663 g_assert_not_reached ();
668 #define CLAUSE_START(clause) ((clause)->try_offset)
669 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
672 * load_store_to_llvm_type:
674 * Return the size/sign/zero extension corresponding to the load/store opcode
678 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
684 case OP_LOADI1_MEMBASE:
685 case OP_STOREI1_MEMBASE_REG:
686 case OP_STOREI1_MEMBASE_IMM:
687 case OP_ATOMIC_LOAD_I1:
688 case OP_ATOMIC_STORE_I1:
691 return LLVMInt8Type ();
692 case OP_LOADU1_MEMBASE:
694 case OP_ATOMIC_LOAD_U1:
695 case OP_ATOMIC_STORE_U1:
698 return LLVMInt8Type ();
699 case OP_LOADI2_MEMBASE:
700 case OP_STOREI2_MEMBASE_REG:
701 case OP_STOREI2_MEMBASE_IMM:
702 case OP_ATOMIC_LOAD_I2:
703 case OP_ATOMIC_STORE_I2:
706 return LLVMInt16Type ();
707 case OP_LOADU2_MEMBASE:
709 case OP_ATOMIC_LOAD_U2:
710 case OP_ATOMIC_STORE_U2:
713 return LLVMInt16Type ();
714 case OP_LOADI4_MEMBASE:
715 case OP_LOADU4_MEMBASE:
718 case OP_STOREI4_MEMBASE_REG:
719 case OP_STOREI4_MEMBASE_IMM:
720 case OP_ATOMIC_LOAD_I4:
721 case OP_ATOMIC_STORE_I4:
722 case OP_ATOMIC_LOAD_U4:
723 case OP_ATOMIC_STORE_U4:
725 return LLVMInt32Type ();
726 case OP_LOADI8_MEMBASE:
728 case OP_STOREI8_MEMBASE_REG:
729 case OP_STOREI8_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I8:
731 case OP_ATOMIC_STORE_I8:
732 case OP_ATOMIC_LOAD_U8:
733 case OP_ATOMIC_STORE_U8:
735 return LLVMInt64Type ();
736 case OP_LOADR4_MEMBASE:
737 case OP_STORER4_MEMBASE_REG:
738 case OP_ATOMIC_LOAD_R4:
739 case OP_ATOMIC_STORE_R4:
741 return LLVMFloatType ();
742 case OP_LOADR8_MEMBASE:
743 case OP_STORER8_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R8:
745 case OP_ATOMIC_STORE_R8:
747 return LLVMDoubleType ();
748 case OP_LOAD_MEMBASE:
750 case OP_STORE_MEMBASE_REG:
751 case OP_STORE_MEMBASE_IMM:
752 *size = sizeof (gpointer);
753 return IntPtrType ();
755 g_assert_not_reached ();
763 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
766 ovf_op_to_intrins (int opcode)
770 return "llvm.sadd.with.overflow.i32";
772 return "llvm.uadd.with.overflow.i32";
774 return "llvm.ssub.with.overflow.i32";
776 return "llvm.usub.with.overflow.i32";
778 return "llvm.smul.with.overflow.i32";
780 return "llvm.umul.with.overflow.i32";
782 return "llvm.sadd.with.overflow.i64";
784 return "llvm.uadd.with.overflow.i64";
786 return "llvm.ssub.with.overflow.i64";
788 return "llvm.usub.with.overflow.i64";
790 return "llvm.smul.with.overflow.i64";
792 return "llvm.umul.with.overflow.i64";
794 g_assert_not_reached ();
800 simd_op_to_intrins (int opcode)
803 #if defined(TARGET_X86) || defined(TARGET_AMD64)
805 return "llvm.x86.sse2.min.pd";
807 return "llvm.x86.sse.min.ps";
809 return "llvm.x86.sse41.pminud";
811 return "llvm.x86.sse41.pminuw";
813 return "llvm.x86.sse2.pminu.b";
815 return "llvm.x86.sse2.pmins.w";
817 return "llvm.x86.sse2.max.pd";
819 return "llvm.x86.sse.max.ps";
821 return "llvm.x86.sse3.hadd.pd";
823 return "llvm.x86.sse3.hadd.ps";
825 return "llvm.x86.sse3.hsub.pd";
827 return "llvm.x86.sse3.hsub.ps";
829 return "llvm.x86.sse41.pmaxud";
831 return "llvm.x86.sse41.pmaxuw";
833 return "llvm.x86.sse2.pmaxu.b";
835 return "llvm.x86.sse3.addsub.ps";
837 return "llvm.x86.sse3.addsub.pd";
838 case OP_EXTRACT_MASK:
839 return "llvm.x86.sse2.pmovmskb.128";
842 return "llvm.x86.sse2.psrli.w";
845 return "llvm.x86.sse2.psrli.d";
848 return "llvm.x86.sse2.psrli.q";
851 return "llvm.x86.sse2.pslli.w";
854 return "llvm.x86.sse2.pslli.d";
857 return "llvm.x86.sse2.pslli.q";
860 return "llvm.x86.sse2.psrai.w";
863 return "llvm.x86.sse2.psrai.d";
865 return "llvm.x86.sse2.padds.b";
867 return "llvm.x86.sse2.padds.w";
869 return "llvm.x86.sse2.psubs.b";
871 return "llvm.x86.sse2.psubs.w";
872 case OP_PADDB_SAT_UN:
873 return "llvm.x86.sse2.paddus.b";
874 case OP_PADDW_SAT_UN:
875 return "llvm.x86.sse2.paddus.w";
876 case OP_PSUBB_SAT_UN:
877 return "llvm.x86.sse2.psubus.b";
878 case OP_PSUBW_SAT_UN:
879 return "llvm.x86.sse2.psubus.w";
881 return "llvm.x86.sse2.pavg.b";
883 return "llvm.x86.sse2.pavg.w";
885 return "llvm.x86.sse.sqrt.ps";
887 return "llvm.x86.sse2.sqrt.pd";
889 return "llvm.x86.sse.rsqrt.ps";
891 return "llvm.x86.sse.rcp.ps";
893 return "llvm.x86.sse2.cvtdq2pd";
895 return "llvm.x86.sse2.cvtdq2ps";
897 return "llvm.x86.sse2.cvtpd2dq";
899 return "llvm.x86.sse2.cvtps2dq";
901 return "llvm.x86.sse2.cvtpd2ps";
903 return "llvm.x86.sse2.cvtps2pd";
905 return "llvm.x86.sse2.cvttpd2dq";
907 return "llvm.x86.sse2.cvttps2dq";
909 return "llvm.x86.sse.cmp.ps";
911 return "llvm.x86.sse2.cmp.pd";
913 return "llvm.x86.sse2.packsswb.128";
915 return "llvm.x86.sse2.packssdw.128";
917 return "llvm.x86.sse2.packuswb.128";
919 return "llvm.x86.sse41.packusdw";
921 return "llvm.x86.sse2.pmulh.w";
922 case OP_PMULW_HIGH_UN:
923 return "llvm.x86.sse2.pmulhu.w";
926 g_assert_not_reached ();
932 simd_op_to_llvm_type (int opcode)
934 #if defined(TARGET_X86) || defined(TARGET_AMD64)
938 return type_to_simd_type (MONO_TYPE_R8);
941 return type_to_simd_type (MONO_TYPE_I8);
944 return type_to_simd_type (MONO_TYPE_I4);
949 return type_to_simd_type (MONO_TYPE_I2);
953 return type_to_simd_type (MONO_TYPE_I1);
955 return type_to_simd_type (MONO_TYPE_R4);
958 return type_to_simd_type (MONO_TYPE_I4);
962 return type_to_simd_type (MONO_TYPE_R8);
966 return type_to_simd_type (MONO_TYPE_R4);
967 case OP_EXTRACT_MASK:
968 return type_to_simd_type (MONO_TYPE_I1);
974 return type_to_simd_type (MONO_TYPE_R4);
977 return type_to_simd_type (MONO_TYPE_R8);
979 g_assert_not_reached ();
990 * Return the LLVM basic block corresponding to BB.
992 static LLVMBasicBlockRef
993 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
995 char bb_name_buf [128];
998 if (ctx->bblocks [bb->block_num].bblock == NULL) {
999 if (bb->flags & BB_EXCEPTION_HANDLER) {
1000 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1001 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1002 bb_name = bb_name_buf;
1003 } else if (bb->block_num < 256) {
1004 if (!ctx->module->bb_names) {
1005 ctx->module->bb_names_len = 256;
1006 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1008 if (!ctx->module->bb_names [bb->block_num]) {
1011 n = g_strdup_printf ("BB%d", bb->block_num);
1012 mono_memory_barrier ();
1013 ctx->module->bb_names [bb->block_num] = n;
1015 bb_name = ctx->module->bb_names [bb->block_num];
1017 sprintf (bb_name_buf, "BB%d", bb->block_num);
1018 bb_name = bb_name_buf;
1021 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1022 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1025 return ctx->bblocks [bb->block_num].bblock;
1031 * Return the last LLVM bblock corresponding to BB.
1032 * This might not be equal to the bb returned by get_bb () since we need to generate
1033 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1035 static LLVMBasicBlockRef
1036 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1039 return ctx->bblocks [bb->block_num].end_bblock;
1042 static LLVMBasicBlockRef
1043 gen_bb (EmitContext *ctx, const char *prefix)
1047 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1048 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1054 * Return the target of the patch identified by TYPE and TARGET.
1057 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1063 memset (&ji, 0, sizeof (ji));
1065 ji.data.target = target;
1067 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1068 mono_error_assert_ok (&error);
1076 * Emit code to convert the LLVM value V to DTYPE.
1079 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1081 LLVMTypeRef stype = LLVMTypeOf (v);
1083 if (stype != dtype) {
1084 gboolean ext = FALSE;
1087 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1089 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1091 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1095 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1097 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1098 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1101 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1102 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1103 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1104 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1105 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1106 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1107 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1108 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1110 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1111 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1112 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1113 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1114 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1115 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1117 if (mono_arch_is_soft_float ()) {
1118 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1119 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1120 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1121 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1124 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1128 LLVMDumpValue (LLVMConstNull (dtype));
1129 g_assert_not_reached ();
1137 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1139 return convert_full (ctx, v, dtype, FALSE);
1143 * emit_volatile_load:
1145 * If vreg is volatile, emit a load from its address.
1148 emit_volatile_load (EmitContext *ctx, int vreg)
1152 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1153 t = ctx->vreg_cli_types [vreg];
1154 if (t && !t->byref) {
1156 * Might have to zero extend since llvm doesn't have
1159 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1160 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1161 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1162 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1163 else if (t->type == MONO_TYPE_U8)
1164 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1171 * emit_volatile_store:
1173 * If VREG is volatile, emit a store from its value to its address.
1176 emit_volatile_store (EmitContext *ctx, int vreg)
1178 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1180 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1181 g_assert (ctx->addresses [vreg]);
1182 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1187 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1189 LLVMTypeRef ret_type;
1190 LLVMTypeRef *param_types = NULL;
1195 rtype = mini_get_underlying_type (sig->ret);
1196 ret_type = type_to_llvm_type (ctx, rtype);
1200 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1204 param_types [pindex ++] = ThisType ();
1205 for (i = 0; i < sig->param_count; ++i)
1206 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1208 if (!ctx_ok (ctx)) {
1209 g_free (param_types);
1213 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1214 g_free (param_types);
1220 * sig_to_llvm_sig_full:
1222 * Return the LLVM signature corresponding to the mono signature SIG using the
1223 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1226 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1228 LLVMTypeRef ret_type;
1229 LLVMTypeRef *param_types = NULL;
1231 int i, j, pindex, vret_arg_pindex = 0;
1232 gboolean vretaddr = FALSE;
1236 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1238 rtype = mini_get_underlying_type (sig->ret);
1239 ret_type = type_to_llvm_type (ctx, rtype);
1243 switch (cinfo->ret.storage) {
1244 case LLVMArgVtypeInReg:
1245 /* LLVM models this by returning an aggregate value */
1246 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1247 LLVMTypeRef members [2];
1249 members [0] = IntPtrType ();
1250 ret_type = LLVMStructType (members, 1, FALSE);
1251 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 ret_type = LLVMVoidType ();
1254 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1255 LLVMTypeRef members [2];
1257 members [0] = IntPtrType ();
1258 members [1] = IntPtrType ();
1259 ret_type = LLVMStructType (members, 2, FALSE);
1261 g_assert_not_reached ();
1264 case LLVMArgVtypeByVal:
1265 /* Vtype returned normally by val */
1267 case LLVMArgVtypeAsScalar: {
1268 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1269 /* LLVM models this by returning an int */
1270 if (size < SIZEOF_VOID_P) {
1271 g_assert (cinfo->ret.nslots == 1);
1272 ret_type = LLVMIntType (size * 8);
1274 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1275 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1279 case LLVMArgFpStruct: {
1280 /* Vtype returned as a fp struct */
1281 LLVMTypeRef members [16];
1283 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1284 for (i = 0; i < cinfo->ret.nslots; ++i)
1285 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1286 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1289 case LLVMArgVtypeByRef:
1290 /* Vtype returned using a hidden argument */
1291 ret_type = LLVMVoidType ();
1293 case LLVMArgVtypeRetAddr:
1294 case LLVMArgScalarRetAddr:
1295 case LLVMArgGsharedvtFixed:
1296 case LLVMArgGsharedvtFixedVtype:
1297 case LLVMArgGsharedvtVariable:
1299 ret_type = LLVMVoidType ();
1305 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1307 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1309 * Has to be the first argument because of the sret argument attribute
1310 * FIXME: This might conflict with passing 'this' as the first argument, but
1311 * this is only used on arm64 which has a dedicated struct return register.
1313 cinfo->vret_arg_pindex = pindex;
1314 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1315 if (!ctx_ok (ctx)) {
1316 g_free (param_types);
1319 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1322 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1323 cinfo->rgctx_arg_pindex = pindex;
1324 param_types [pindex] = ctx->module->ptr_type;
1327 if (cinfo->imt_arg) {
1328 cinfo->imt_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1333 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1334 vret_arg_pindex = pindex;
1335 if (cinfo->vret_arg_index == 1) {
1336 /* Add the slots consumed by the first argument */
1337 LLVMArgInfo *ainfo = &cinfo->args [0];
1338 switch (ainfo->storage) {
1339 case LLVMArgVtypeInReg:
1340 for (j = 0; j < 2; ++j) {
1341 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1350 cinfo->vret_arg_pindex = vret_arg_pindex;
1353 if (vretaddr && vret_arg_pindex == pindex)
1354 param_types [pindex ++] = IntPtrType ();
1356 cinfo->this_arg_pindex = pindex;
1357 param_types [pindex ++] = ThisType ();
1358 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1360 if (vretaddr && vret_arg_pindex == pindex)
1361 param_types [pindex ++] = IntPtrType ();
1362 for (i = 0; i < sig->param_count; ++i) {
1363 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 ainfo->pindex = pindex;
1369 switch (ainfo->storage) {
1370 case LLVMArgVtypeInReg:
1371 for (j = 0; j < 2; ++j) {
1372 switch (ainfo->pair_storage [j]) {
1374 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1379 g_assert_not_reached ();
1383 case LLVMArgVtypeByVal:
1384 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1387 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1390 case LLVMArgAsIArgs:
1391 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1394 case LLVMArgVtypeByRef:
1395 case LLVMArgScalarByRef:
1396 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1399 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1402 case LLVMArgAsFpArgs: {
1405 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1406 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1407 param_types [pindex ++] = LLVMDoubleType ();
1408 for (j = 0; j < ainfo->nslots; ++j)
1409 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1412 case LLVMArgVtypeAsScalar:
1413 g_assert_not_reached ();
1415 case LLVMArgGsharedvtFixed:
1416 case LLVMArgGsharedvtFixedVtype:
1417 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1419 case LLVMArgGsharedvtVariable:
1420 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1423 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 if (!ctx_ok (ctx)) {
1428 g_free (param_types);
1431 if (vretaddr && vret_arg_pindex == pindex)
1432 param_types [pindex ++] = IntPtrType ();
1433 if (ctx->llvm_only && cinfo->rgctx_arg) {
1434 /* Pass the rgctx as the last argument */
1435 cinfo->rgctx_arg_pindex = pindex;
1436 param_types [pindex] = ctx->module->ptr_type;
1440 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1441 g_free (param_types);
1447 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1449 return sig_to_llvm_sig_full (ctx, sig, NULL);
1453 * LLVMFunctionType1:
1455 * Create an LLVM function type from the arguments.
1457 static G_GNUC_UNUSED LLVMTypeRef
1458 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1461 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1465 * LLVMFunctionType1:
1467 * Create an LLVM function type from the arguments.
1469 static G_GNUC_UNUSED LLVMTypeRef
1470 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1471 LLVMTypeRef ParamType1,
1474 LLVMTypeRef param_types [1];
1476 param_types [0] = ParamType1;
1478 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1482 * LLVMFunctionType2:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1492 LLVMTypeRef param_types [2];
1494 param_types [0] = ParamType1;
1495 param_types [1] = ParamType2;
1497 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1501 * LLVMFunctionType3:
1503 * Create an LLVM function type from the arguments.
1505 static G_GNUC_UNUSED LLVMTypeRef
1506 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1507 LLVMTypeRef ParamType1,
1508 LLVMTypeRef ParamType2,
1509 LLVMTypeRef ParamType3,
1512 LLVMTypeRef param_types [3];
1514 param_types [0] = ParamType1;
1515 param_types [1] = ParamType2;
1516 param_types [2] = ParamType3;
1518 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1521 static G_GNUC_UNUSED LLVMTypeRef
1522 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1523 LLVMTypeRef ParamType1,
1524 LLVMTypeRef ParamType2,
1525 LLVMTypeRef ParamType3,
1526 LLVMTypeRef ParamType4,
1527 LLVMTypeRef ParamType5,
1530 LLVMTypeRef param_types [5];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1534 param_types [2] = ParamType3;
1535 param_types [3] = ParamType4;
1536 param_types [4] = ParamType5;
1538 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1544 * Create an LLVM builder and remember it so it can be freed later.
1546 static LLVMBuilderRef
1547 create_builder (EmitContext *ctx)
1549 LLVMBuilderRef builder = LLVMCreateBuilder ();
1551 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1557 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1562 case MONO_PATCH_INFO_INTERNAL_METHOD:
1563 name = g_strdup_printf ("jit_icall_%s", data);
1565 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1566 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1567 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1571 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1579 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1583 LLVMValueRef indexes [2];
1585 LLVMValueRef got_entry_addr, load;
1586 LLVMBuilderRef builder = ctx->builder;
1591 ji = g_new0 (MonoJumpInfo, 1);
1593 ji->data.target = data;
1595 ji = mono_aot_patch_info_dup (ji);
1597 ji->next = cfg->patch_info;
1598 cfg->patch_info = ji;
1600 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1601 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1603 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1604 * explicitly initialize it.
1606 if (!mono_aot_is_shared_got_offset (got_offset)) {
1607 //mono_print_ji (ji);
1609 ctx->has_got_access = TRUE;
1612 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1613 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1614 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1616 name = get_aotconst_name (type, data, got_offset);
1618 load = LLVMBuildLoad (builder, got_entry_addr, "");
1619 load = convert (ctx, load, llvm_type);
1620 LLVMSetValueName (load, name ? name : "");
1622 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1625 //set_invariant_load_flag (load);
1631 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1633 return get_aotconst_typed (ctx, type, data, NULL);
1637 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1639 LLVMValueRef callee;
1641 if (ctx->llvm_only) {
1642 callee_name = mono_aot_get_direct_call_symbol (type, data);
1644 /* Directly callable */
1646 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1648 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1650 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1652 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1654 /* LLVMTypeRef's are uniqued */
1655 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1656 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1658 g_free (callee_name);
1664 * Calls are made through the GOT.
1666 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1668 MonoJumpInfo *ji = NULL;
1670 callee_name = mono_aot_get_plt_symbol (type, data);
1674 if (ctx->cfg->compile_aot)
1675 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1676 mono_add_patch_info (ctx->cfg, 0, type, data);
1679 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1681 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1683 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1685 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1688 if (ctx->cfg->compile_aot) {
1689 ji = g_new0 (MonoJumpInfo, 1);
1691 ji->data.target = data;
1693 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1701 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1703 MonoMethodHeader *header = cfg->header;
1704 MonoExceptionClause *clause;
1708 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1709 return (bb->region >> 8) - 1;
1712 for (i = 0; i < header->num_clauses; ++i) {
1713 clause = &header->clauses [i];
1715 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1722 static MonoExceptionClause *
1723 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1725 // Since they're sorted by nesting we just need
1726 // the first one that the bb is a member of
1727 MonoExceptionClause *last = NULL;
1729 for (int i = 0; i < cfg->header->num_clauses; i++) {
1730 MonoExceptionClause *curr = &cfg->header->clauses [i];
1732 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1735 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1736 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1750 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1752 LLVMValueRef md_arg;
1755 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1756 md_arg = LLVMMDString ("mono", 4);
1757 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1761 set_invariant_load_flag (LLVMValueRef v)
1763 LLVMValueRef md_arg;
1765 const char *flag_name;
1767 // FIXME: Cache this
1768 flag_name = "invariant.load";
1769 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1770 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1771 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1777 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1781 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1783 MonoCompile *cfg = ctx->cfg;
1784 LLVMValueRef lcall = NULL;
1785 LLVMBuilderRef builder = *builder_ref;
1786 MonoExceptionClause *clause;
1788 if (ctx->llvm_only) {
1789 clause = get_most_deep_clause (cfg, ctx, bb);
1792 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1795 * Have to use an invoke instead of a call, branching to the
1796 * handler bblock of the clause containing this bblock.
1798 intptr_t key = CLAUSE_END(clause);
1800 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1802 // FIXME: Find the one that has the lowest end bound for the right start address
1803 // FIXME: Finally + nesting
1806 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1809 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1811 builder = ctx->builder = create_builder (ctx);
1812 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1814 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1818 int clause_index = get_handler_clause (cfg, bb);
1820 if (clause_index != -1) {
1821 MonoMethodHeader *header = cfg->header;
1822 MonoExceptionClause *ec = &header->clauses [clause_index];
1823 MonoBasicBlock *tblock;
1824 LLVMBasicBlockRef ex_bb, noex_bb;
1827 * Have to use an invoke instead of a call, branching to the
1828 * handler bblock of the clause containing this bblock.
1831 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1833 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1836 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1838 ex_bb = get_bb (ctx, tblock);
1840 noex_bb = gen_bb (ctx, "NOEX_BB");
1843 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1845 builder = ctx->builder = create_builder (ctx);
1846 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1848 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1853 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1854 ctx->builder = builder;
1858 *builder_ref = ctx->builder;
1864 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1866 const char *intrins_name;
1867 LLVMValueRef args [16], res;
1868 LLVMTypeRef addr_type;
1869 gboolean use_intrinsics = TRUE;
1871 #if LLVM_API_VERSION > 100
1872 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1873 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1874 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1875 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1876 *builder_ref = ctx->builder;
1877 use_intrinsics = FALSE;
1881 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1882 LLVMAtomicOrdering ordering;
1885 case LLVM_BARRIER_NONE:
1886 ordering = LLVMAtomicOrderingNotAtomic;
1888 case LLVM_BARRIER_ACQ:
1889 ordering = LLVMAtomicOrderingAcquire;
1891 case LLVM_BARRIER_SEQ:
1892 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1895 g_assert_not_reached ();
1900 * We handle loads which can fault by calling a mono specific intrinsic
1901 * using an invoke, so they are handled properly inside try blocks.
1902 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1903 * are marked with IntrReadArgMem.
1907 intrins_name = "llvm.mono.load.i8.p0i8";
1910 intrins_name = "llvm.mono.load.i16.p0i16";
1913 intrins_name = "llvm.mono.load.i32.p0i32";
1916 intrins_name = "llvm.mono.load.i64.p0i64";
1919 g_assert_not_reached ();
1922 addr_type = LLVMTypeOf (addr);
1923 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1924 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1927 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1928 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1929 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1930 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1932 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1933 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1934 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1942 * We emit volatile loads for loads which can fault, because otherwise
1943 * LLVM will generate invalid code when encountering a load from a
1946 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1948 /* Mark it with a custom metadata */
1951 set_metadata_flag (res, "mono.faulting.load");
1959 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1961 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1965 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1967 const char *intrins_name;
1968 LLVMValueRef args [16];
1969 gboolean use_intrinsics = TRUE;
1971 #if LLVM_API_VERSION > 100
1972 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1973 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1974 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1975 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1976 *builder_ref = ctx->builder;
1977 use_intrinsics = FALSE;
1981 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1982 LLVMAtomicOrdering ordering;
1985 case LLVM_BARRIER_NONE:
1986 ordering = LLVMAtomicOrderingNotAtomic;
1988 case LLVM_BARRIER_REL:
1989 ordering = LLVMAtomicOrderingRelease;
1991 case LLVM_BARRIER_SEQ:
1992 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1995 g_assert_not_reached ();
2001 intrins_name = "llvm.mono.store.i8.p0i8";
2004 intrins_name = "llvm.mono.store.i16.p0i16";
2007 intrins_name = "llvm.mono.store.i32.p0i32";
2010 intrins_name = "llvm.mono.store.i64.p0i64";
2013 g_assert_not_reached ();
2016 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2017 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2018 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2023 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2024 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2025 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2026 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2028 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2033 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2035 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2039 * emit_cond_system_exception:
2041 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2042 * Might set the ctx exception.
2045 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2047 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2048 LLVMBuilderRef builder;
2049 MonoClass *exc_class;
2050 LLVMValueRef args [2];
2051 LLVMValueRef callee;
2053 ex_bb = gen_bb (ctx, "EX_BB");
2055 ex2_bb = gen_bb (ctx, "EX2_BB");
2056 noex_bb = gen_bb (ctx, "NOEX_BB");
2058 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2060 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2062 /* Emit exception throwing code */
2063 ctx->builder = builder = create_builder (ctx);
2064 LLVMPositionBuilderAtEnd (builder, ex_bb);
2066 if (ctx->cfg->llvm_only) {
2067 static LLVMTypeRef sig;
2070 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2071 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2073 LLVMBuildBr (builder, ex2_bb);
2075 ctx->builder = builder = create_builder (ctx);
2076 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2078 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2079 emit_call (ctx, bb, &builder, callee, args, 1);
2080 LLVMBuildUnreachable (builder);
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2085 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2091 callee = ctx->module->throw_corlib_exception;
2094 const char *icall_name;
2096 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2097 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2099 if (ctx->cfg->compile_aot) {
2100 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2102 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2105 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2106 * - On x86, LLVM generated code doesn't push the arguments
2107 * - The trampoline takes the throw address as an arguments, not a pc offset.
2109 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2111 mono_memory_barrier ();
2112 ctx->module->throw_corlib_exception = callee;
2116 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2117 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2119 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2122 * The LLVM mono branch contains changes so a block address can be passed as an
2123 * argument to a call.
2125 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2126 emit_call (ctx, bb, &builder, callee, args, 2);
2128 LLVMBuildUnreachable (builder);
2130 ctx->builder = builder = create_builder (ctx);
2131 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2133 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2140 * emit_args_to_vtype:
2142 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2145 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2147 int j, size, nslots;
2149 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2151 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2152 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2155 if (ainfo->storage == LLVMArgAsFpArgs)
2156 nslots = ainfo->nslots;
2160 for (j = 0; j < nslots; ++j) {
2161 LLVMValueRef index [2], addr, daddr;
2162 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2163 LLVMTypeRef part_type;
2165 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2168 if (ainfo->pair_storage [j] == LLVMArgNone)
2171 switch (ainfo->pair_storage [j]) {
2172 case LLVMArgInIReg: {
2173 part_type = LLVMIntType (part_size * 8);
2174 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2175 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2176 addr = LLVMBuildGEP (builder, address, index, 1, "");
2178 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2179 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2180 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2182 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2185 case LLVMArgInFPReg: {
2186 LLVMTypeRef arg_type;
2188 if (ainfo->esize == 8)
2189 arg_type = LLVMDoubleType ();
2191 arg_type = LLVMFloatType ();
2193 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2194 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2195 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2196 LLVMBuildStore (builder, args [j], addr);
2202 g_assert_not_reached ();
2205 size -= sizeof (gpointer);
2210 * emit_vtype_to_args:
2212 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2213 * into ARGS, and the number of arguments into NARGS.
2216 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2219 int j, size, nslots;
2220 LLVMTypeRef arg_type;
2222 size = get_vtype_size (t);
2224 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2225 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2227 if (ainfo->storage == LLVMArgAsFpArgs)
2228 nslots = ainfo->nslots;
2231 for (j = 0; j < nslots; ++j) {
2232 LLVMValueRef index [2], addr, daddr;
2233 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2235 if (ainfo->pair_storage [j] == LLVMArgNone)
2238 switch (ainfo->pair_storage [j]) {
2240 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2241 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2242 addr = LLVMBuildGEP (builder, address, index, 1, "");
2244 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2245 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2246 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2248 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2250 case LLVMArgInFPReg:
2251 if (ainfo->esize == 8)
2252 arg_type = LLVMDoubleType ();
2254 arg_type = LLVMFloatType ();
2255 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2256 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2257 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2258 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2263 g_assert_not_reached ();
2265 size -= sizeof (gpointer);
2272 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2275 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2276 * get executed every time control reaches them.
2278 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2280 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2281 return ctx->last_alloca;
2285 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2287 return build_alloca_llvm_type_name (ctx, t, align, "");
2291 build_alloca (EmitContext *ctx, MonoType *t)
2293 MonoClass *k = mono_class_from_mono_type (t);
2296 g_assert (!mini_is_gsharedvt_variable_type (t));
2298 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2301 align = mono_class_min_align (k);
2303 /* Sometimes align is not a power of 2 */
2304 while (mono_is_power_of_two (align) == -1)
2307 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2311 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2315 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2317 MonoCompile *cfg = ctx->cfg;
2318 LLVMBuilderRef builder = ctx->builder;
2319 LLVMValueRef offset, offset_var;
2320 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2321 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2325 g_assert (info_var);
2326 g_assert (locals_var);
2328 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2330 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2331 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2333 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2334 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2336 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2340 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2343 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2346 module->used = g_ptr_array_sized_new (16);
2347 g_ptr_array_add (module->used, global);
2351 emit_llvm_used (MonoLLVMModule *module)
2353 LLVMModuleRef lmodule = module->lmodule;
2354 LLVMTypeRef used_type;
2355 LLVMValueRef used, *used_elem;
2361 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2362 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2363 used_elem = g_new0 (LLVMValueRef, module->used->len);
2364 for (i = 0; i < module->used->len; ++i)
2365 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2366 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2367 LLVMSetLinkage (used, LLVMAppendingLinkage);
2368 LLVMSetSection (used, "llvm.metadata");
2374 * Emit a function mapping method indexes to their code
2377 emit_get_method (MonoLLVMModule *module)
2379 LLVMModuleRef lmodule = module->lmodule;
2380 LLVMValueRef func, switch_ins, m;
2381 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2382 LLVMBasicBlockRef *bbs;
2384 LLVMBuilderRef builder;
2389 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2390 * but generating code seems safer.
2392 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2393 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2394 LLVMSetLinkage (func, LLVMExternalLinkage);
2395 LLVMSetVisibility (func, LLVMHiddenVisibility);
2396 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2397 module->get_method = func;
2399 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2402 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2403 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2404 * then we will have to find another solution.
2407 name = g_strdup_printf ("BB_CODE_START");
2408 code_start_bb = LLVMAppendBasicBlock (func, name);
2410 builder = LLVMCreateBuilder ();
2411 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2412 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2414 name = g_strdup_printf ("BB_CODE_END");
2415 code_end_bb = LLVMAppendBasicBlock (func, name);
2417 builder = LLVMCreateBuilder ();
2418 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2419 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2421 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2422 for (i = 0; i < module->max_method_idx + 1; ++i) {
2423 name = g_strdup_printf ("BB_%d", i);
2424 bb = LLVMAppendBasicBlock (func, name);
2428 builder = LLVMCreateBuilder ();
2429 LLVMPositionBuilderAtEnd (builder, bb);
2431 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2433 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2435 LLVMBuildRet (builder, LLVMConstNull (rtype));
2438 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2439 builder = LLVMCreateBuilder ();
2440 LLVMPositionBuilderAtEnd (builder, fail_bb);
2441 LLVMBuildRet (builder, LLVMConstNull (rtype));
2443 builder = LLVMCreateBuilder ();
2444 LLVMPositionBuilderAtEnd (builder, entry_bb);
2446 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2447 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2448 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2449 for (i = 0; i < module->max_method_idx + 1; ++i) {
2450 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2453 mark_as_used (module, func);
2457 * emit_get_unbox_tramp:
2459 * Emit a function mapping method indexes to their unbox trampoline
2462 emit_get_unbox_tramp (MonoLLVMModule *module)
2464 LLVMModuleRef lmodule = module->lmodule;
2465 LLVMValueRef func, switch_ins, m;
2466 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2467 LLVMBasicBlockRef *bbs;
2469 LLVMBuilderRef builder;
2473 /* Similar to emit_get_method () */
2475 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2476 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2477 LLVMSetLinkage (func, LLVMExternalLinkage);
2478 LLVMSetVisibility (func, LLVMHiddenVisibility);
2479 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2480 module->get_unbox_tramp = func;
2482 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2484 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2485 for (i = 0; i < module->max_method_idx + 1; ++i) {
2486 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2490 name = g_strdup_printf ("BB_%d", i);
2491 bb = LLVMAppendBasicBlock (func, name);
2495 builder = LLVMCreateBuilder ();
2496 LLVMPositionBuilderAtEnd (builder, bb);
2498 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2501 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2502 builder = LLVMCreateBuilder ();
2503 LLVMPositionBuilderAtEnd (builder, fail_bb);
2504 LLVMBuildRet (builder, LLVMConstNull (rtype));
2506 builder = LLVMCreateBuilder ();
2507 LLVMPositionBuilderAtEnd (builder, entry_bb);
2509 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2510 for (i = 0; i < module->max_method_idx + 1; ++i) {
2511 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2518 mark_as_used (module, func);
2521 /* Add a function to mark the beginning of LLVM code */
2523 emit_llvm_code_start (MonoLLVMModule *module)
2525 LLVMModuleRef lmodule = module->lmodule;
2527 LLVMBasicBlockRef entry_bb;
2528 LLVMBuilderRef builder;
2530 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2531 LLVMSetLinkage (func, LLVMInternalLinkage);
2532 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2533 module->code_start = func;
2534 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2537 LLVMBuildRetVoid (builder);
2541 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2543 LLVMModuleRef lmodule = module->lmodule;
2544 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2545 LLVMBasicBlockRef entry_bb;
2546 LLVMBuilderRef builder;
2553 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2554 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2559 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2560 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2563 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2564 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2567 g_assert_not_reached ();
2569 LLVMSetLinkage (func, LLVMInternalLinkage);
2570 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2571 mono_llvm_set_preserveall_cc (func);
2572 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2573 builder = LLVMCreateBuilder ();
2574 LLVMPositionBuilderAtEnd (builder, entry_bb);
2577 ji = g_new0 (MonoJumpInfo, 1);
2578 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2579 ji = mono_aot_patch_info_dup (ji);
2580 got_offset = mono_aot_get_got_offset (ji);
2581 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2582 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2583 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2584 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2585 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2586 args [1] = LLVMGetParam (func, 0);
2588 args [2] = LLVMGetParam (func, 1);
2590 ji = g_new0 (MonoJumpInfo, 1);
2591 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2592 ji->data.name = icall_name;
2593 ji = mono_aot_patch_info_dup (ji);
2594 got_offset = mono_aot_get_got_offset (ji);
2595 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2596 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2597 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2598 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2599 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2600 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2601 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2603 // Set the inited flag
2604 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2605 indexes [1] = LLVMGetParam (func, 0);
2606 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2608 LLVMBuildRetVoid (builder);
2610 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2615 * Emit wrappers around the C icalls used to initialize llvm methods, to
2616 * make the calling code smaller and to enable usage of the llvm
2617 * PreserveAll calling convention.
2620 emit_init_icall_wrappers (MonoLLVMModule *module)
2622 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2623 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2624 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2625 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2629 emit_llvm_code_end (MonoLLVMModule *module)
2631 LLVMModuleRef lmodule = module->lmodule;
2633 LLVMBasicBlockRef entry_bb;
2634 LLVMBuilderRef builder;
2636 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2637 LLVMSetLinkage (func, LLVMInternalLinkage);
2638 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2639 module->code_end = func;
2640 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2641 builder = LLVMCreateBuilder ();
2642 LLVMPositionBuilderAtEnd (builder, entry_bb);
2643 LLVMBuildRetVoid (builder);
2647 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2649 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2652 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2653 need_div_check = TRUE;
2655 if (!need_div_check)
2658 switch (ins->opcode) {
2671 case OP_IDIV_UN_IMM:
2672 case OP_LDIV_UN_IMM:
2673 case OP_IREM_UN_IMM:
2674 case OP_LREM_UN_IMM: {
2676 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2677 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2679 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2680 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2683 builder = ctx->builder;
2685 /* b == -1 && a == 0x80000000 */
2687 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2688 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2689 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2691 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2692 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2695 builder = ctx->builder;
2707 * Emit code to initialize the GOT slots used by the method.
2710 emit_init_method (EmitContext *ctx)
2712 LLVMValueRef indexes [16], args [16], callee;
2713 LLVMValueRef inited_var, cmp, call;
2714 LLVMBasicBlockRef inited_bb, notinited_bb;
2715 LLVMBuilderRef builder = ctx->builder;
2716 MonoCompile *cfg = ctx->cfg;
2718 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2720 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2721 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2722 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2724 args [0] = inited_var;
2725 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2726 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2728 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2730 inited_bb = ctx->inited_bb;
2731 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2733 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2735 builder = ctx->builder = create_builder (ctx);
2736 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2739 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2740 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2741 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2742 callee = ctx->module->init_method_gshared_mrgctx;
2743 call = LLVMBuildCall (builder, callee, args, 2, "");
2744 } else if (ctx->rgctx_arg) {
2745 /* A vtable is passed as the rgctx argument */
2746 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2747 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2748 callee = ctx->module->init_method_gshared_vtable;
2749 call = LLVMBuildCall (builder, callee, args, 2, "");
2750 } else if (cfg->gshared) {
2751 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2752 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2753 callee = ctx->module->init_method_gshared_this;
2754 call = LLVMBuildCall (builder, callee, args, 2, "");
2756 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2757 callee = ctx->module->init_method;
2758 call = LLVMBuildCall (builder, callee, args, 1, "");
2762 * This enables llvm to keep arguments in their original registers/
2763 * scratch registers, since the call will not clobber them.
2765 mono_llvm_set_call_preserveall_cc (call);
2767 LLVMBuildBr (builder, inited_bb);
2768 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2770 builder = ctx->builder = create_builder (ctx);
2771 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2775 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2778 * Emit unbox trampoline using a tail call
2780 LLVMValueRef tramp, call, *args;
2781 LLVMBuilderRef builder;
2782 LLVMBasicBlockRef lbb;
2783 LLVMCallInfo *linfo;
2787 tramp_name = g_strdup_printf ("ut_%s", method_name);
2788 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2789 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2790 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2791 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2793 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2794 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2795 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2796 if (ctx->cfg->vret_addr) {
2797 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2798 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2799 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2800 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2804 lbb = LLVMAppendBasicBlock (tramp, "");
2805 builder = LLVMCreateBuilder ();
2806 LLVMPositionBuilderAtEnd (builder, lbb);
2808 nargs = LLVMCountParamTypes (method_type);
2809 args = g_new0 (LLVMValueRef, nargs);
2810 for (i = 0; i < nargs; ++i) {
2811 args [i] = LLVMGetParam (tramp, i);
2812 if (i == ctx->this_arg_pindex) {
2813 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2815 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2816 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2817 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2820 call = LLVMBuildCall (builder, method, args, nargs, "");
2821 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2822 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2823 if (linfo->ret.storage == LLVMArgVtypeByRef)
2824 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2826 // FIXME: This causes assertions in clang
2827 //mono_llvm_set_must_tail (call);
2828 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2829 LLVMBuildRetVoid (builder);
2831 LLVMBuildRet (builder, call);
2833 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2839 * Emit code to load/convert arguments.
2842 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2845 MonoCompile *cfg = ctx->cfg;
2846 MonoMethodSignature *sig = ctx->sig;
2847 LLVMCallInfo *linfo = ctx->linfo;
2851 LLVMBuilderRef old_builder = ctx->builder;
2852 ctx->builder = builder;
2854 ctx->alloca_builder = create_builder (ctx);
2857 * Handle indirect/volatile variables by allocating memory for them
2858 * using 'alloca', and storing their address in a temporary.
2860 for (i = 0; i < cfg->num_varinfo; ++i) {
2861 MonoInst *var = cfg->varinfo [i];
2864 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2865 } 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))) {
2866 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2869 /* Could be already created by an OP_VPHI */
2870 if (!ctx->addresses [var->dreg]) {
2871 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2872 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2874 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2878 names = g_new (char *, sig->param_count);
2879 mono_method_get_param_names (cfg->method, (const char **) names);
2881 for (i = 0; i < sig->param_count; ++i) {
2882 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2883 int reg = cfg->args [i + sig->hasthis]->dreg;
2886 pindex = ainfo->pindex;
2888 switch (ainfo->storage) {
2889 case LLVMArgVtypeInReg:
2890 case LLVMArgAsFpArgs: {
2891 LLVMValueRef args [8];
2894 pindex += ainfo->ndummy_fpargs;
2896 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2897 memset (args, 0, sizeof (args));
2898 if (ainfo->storage == LLVMArgVtypeInReg) {
2899 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2900 if (ainfo->pair_storage [1] != LLVMArgNone)
2901 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2903 g_assert (ainfo->nslots <= 8);
2904 for (j = 0; j < ainfo->nslots; ++j)
2905 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2907 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2909 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2911 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2912 /* Treat these as normal values */
2913 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2917 case LLVMArgVtypeByVal: {
2918 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2920 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2921 /* Treat these as normal values */
2922 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2926 case LLVMArgVtypeByRef: {
2927 /* The argument is passed by ref */
2928 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2931 case LLVMArgScalarByRef: {
2933 name = g_strdup_printf ("arg_%s", names [i]);
2935 name = g_strdup_printf ("arg_%d", i);
2936 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2940 case LLVMArgAsIArgs: {
2941 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2944 /* The argument is received as an array of ints, store it into the real argument */
2945 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2947 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2948 if (size < SIZEOF_VOID_P) {
2949 /* The upper bits of the registers might not be valid */
2950 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2951 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2952 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2954 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2958 case LLVMArgVtypeAsScalar:
2959 g_assert_not_reached ();
2961 case LLVMArgGsharedvtFixed: {
2962 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2963 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2966 name = g_strdup_printf ("arg_%s", names [i]);
2968 name = g_strdup_printf ("arg_%d", i);
2970 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2973 case LLVMArgGsharedvtFixedVtype: {
2974 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2977 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2979 name = g_strdup_printf ("vtype_arg_%d", i);
2981 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2982 g_assert (ctx->addresses [reg]);
2983 LLVMSetValueName (ctx->addresses [reg], name);
2984 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2987 case LLVMArgGsharedvtVariable:
2988 /* The IR treats these as variables with addresses */
2989 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2992 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));
2999 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3001 emit_volatile_store (ctx, cfg->args [0]->dreg);
3002 for (i = 0; i < sig->param_count; ++i)
3003 if (!mini_type_is_vtype (sig->params [i]))
3004 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3006 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3007 LLVMValueRef this_alloc;
3010 * The exception handling code needs the location where the this argument was
3011 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3012 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3013 * location into the LSDA.
3015 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3016 /* This volatile store will keep the alloca alive */
3017 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3019 set_metadata_flag (this_alloc, "mono.this");
3022 if (cfg->rgctx_var) {
3023 LLVMValueRef rgctx_alloc, store;
3026 * We handle the rgctx arg similarly to the this pointer.
3028 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3029 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3030 /* This volatile store will keep the alloca alive */
3031 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3033 set_metadata_flag (rgctx_alloc, "mono.this");
3036 /* Initialize the method if needed */
3037 if (cfg->compile_aot && ctx->llvm_only) {
3038 /* Emit a location for the initialization code */
3039 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3040 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3042 LLVMBuildBr (ctx->builder, ctx->init_bb);
3043 builder = ctx->builder = create_builder (ctx);
3044 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3045 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3048 /* Compute nesting between clauses */
3049 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3050 for (i = 0; i < cfg->header->num_clauses; ++i) {
3051 for (j = 0; j < cfg->header->num_clauses; ++j) {
3052 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3053 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3055 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3056 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3061 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3062 * it needs to continue normally, or return back to the exception handling system.
3064 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3068 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3071 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3072 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3073 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3075 if (bb->in_scount == 0) {
3078 sprintf (name, "finally_ind_bb%d", bb->block_num);
3079 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3080 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3082 ctx->bblocks [bb->block_num].finally_ind = val;
3084 /* Create a variable to hold the exception var */
3086 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3090 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3091 * LLVM bblock containing a landing pad causes problems for the
3092 * LLVM optimizer passes.
3094 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3095 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3097 ctx->builder = old_builder;
3101 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3103 MonoCompile *cfg = ctx->cfg;
3104 LLVMModuleRef lmodule = ctx->lmodule;
3105 LLVMValueRef *values = ctx->values;
3106 LLVMValueRef *addresses = ctx->addresses;
3107 MonoCallInst *call = (MonoCallInst*)ins;
3108 MonoMethodSignature *sig = call->signature;
3109 LLVMValueRef callee = NULL, lcall;
3111 LLVMCallInfo *cinfo;
3115 LLVMTypeRef llvm_sig;
3117 gboolean is_virtual, calli, preserveall;
3118 LLVMBuilderRef builder = *builder_ref;
3120 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3121 set_failure (ctx, "non-default callconv");
3125 cinfo = call->cinfo;
3127 if (call->rgctx_arg_reg)
3128 cinfo->rgctx_arg = TRUE;
3129 if (call->imt_arg_reg)
3130 cinfo->imt_arg = TRUE;
3132 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);
3134 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3138 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);
3139 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);
3141 preserveall = FALSE;
3143 /* FIXME: Avoid creating duplicate methods */
3145 if (ins->flags & MONO_INST_HAS_METHOD) {
3149 if (cfg->compile_aot) {
3150 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3152 set_failure (ctx, "can't encode patch");
3155 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3157 * Collect instructions representing the callee into a hash so they can be replaced
3158 * by the llvm method for the callee if the callee turns out to be direct
3159 * callable. Currently this only requires it to not fail llvm compilation.
3161 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3162 l = g_slist_prepend (l, callee);
3163 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3166 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3169 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3171 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3175 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3176 /* LLVM miscompiles async methods */
3177 set_failure (ctx, "#13734");
3182 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3188 memset (&ji, 0, sizeof (ji));
3189 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3190 ji.data.target = info->name;
3192 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3194 if (cfg->compile_aot) {
3195 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3197 set_failure (ctx, "can't encode patch");
3201 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3202 target = (gpointer)mono_icall_get_wrapper (info);
3203 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3206 if (cfg->compile_aot) {
3208 if (cfg->abs_patches) {
3209 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3211 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3213 set_failure (ctx, "can't encode patch");
3219 set_failure (ctx, "aot");
3223 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3225 if (cfg->abs_patches) {
3226 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3231 * FIXME: Some trampolines might have
3232 * their own calling convention on some platforms.
3234 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3235 mono_error_assert_ok (&error);
3236 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3240 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3246 int size = sizeof (gpointer);
3249 g_assert (ins->inst_offset % size == 0);
3250 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3252 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3254 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3256 if (ins->flags & MONO_INST_HAS_METHOD) {
3261 * Collect and convert arguments
3263 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3264 len = sizeof (LLVMValueRef) * nargs;
3265 args = (LLVMValueRef*)alloca (len);
3266 memset (args, 0, len);
3267 l = call->out_ireg_args;
3269 if (call->rgctx_arg_reg) {
3270 g_assert (values [call->rgctx_arg_reg]);
3271 g_assert (cinfo->rgctx_arg_pindex < nargs);
3273 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3274 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3275 * it using a volatile load.
3278 if (!ctx->imt_rgctx_loc)
3279 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3280 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3281 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3283 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3286 if (call->imt_arg_reg) {
3287 g_assert (!ctx->llvm_only);
3288 g_assert (values [call->imt_arg_reg]);
3289 g_assert (cinfo->imt_arg_pindex < nargs);
3291 if (!ctx->imt_rgctx_loc)
3292 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3293 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3294 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3296 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3299 switch (cinfo->ret.storage) {
3300 case LLVMArgGsharedvtVariable: {
3301 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3303 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3304 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3306 g_assert (addresses [call->inst.dreg]);
3307 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3313 if (!addresses [call->inst.dreg])
3314 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3315 g_assert (cinfo->vret_arg_pindex < nargs);
3316 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3317 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3319 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3325 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3326 * use the real callee for argument type conversion.
3328 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3329 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3330 LLVMGetParamTypes (callee_type, param_types);
3332 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3335 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3337 pindex = ainfo->pindex;
3339 regpair = (guint32)(gssize)(l->data);
3340 reg = regpair & 0xffffff;
3341 args [pindex] = values [reg];
3342 switch (ainfo->storage) {
3343 case LLVMArgVtypeInReg:
3344 case LLVMArgAsFpArgs: {
3348 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3349 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3350 pindex += ainfo->ndummy_fpargs;
3352 g_assert (addresses [reg]);
3353 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3357 // FIXME: Get rid of the VMOVE
3360 case LLVMArgVtypeByVal:
3361 g_assert (addresses [reg]);
3362 args [pindex] = addresses [reg];
3364 case LLVMArgVtypeByRef:
3365 case LLVMArgScalarByRef: {
3366 g_assert (addresses [reg]);
3367 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3370 case LLVMArgAsIArgs:
3371 g_assert (addresses [reg]);
3372 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3374 case LLVMArgVtypeAsScalar:
3375 g_assert_not_reached ();
3377 case LLVMArgGsharedvtFixed:
3378 case LLVMArgGsharedvtFixedVtype:
3379 g_assert (addresses [reg]);
3380 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3382 case LLVMArgGsharedvtVariable:
3383 g_assert (addresses [reg]);
3384 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3387 g_assert (args [pindex]);
3388 if (i == 0 && sig->hasthis)
3389 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3391 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3394 g_assert (pindex <= nargs);
3399 // FIXME: Align call sites
3405 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3408 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3410 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3411 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3413 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3414 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3415 if (!sig->pinvoke && !cfg->llvm_only)
3416 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3418 mono_llvm_set_call_preserveall_cc (lcall);
3420 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3421 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3422 if (!ctx->llvm_only && call->rgctx_arg_reg)
3423 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3424 if (call->imt_arg_reg)
3425 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3427 /* Add byval attributes if needed */
3428 for (i = 0; i < sig->param_count; ++i) {
3429 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3431 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3432 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3436 * Convert the result
3438 switch (cinfo->ret.storage) {
3439 case LLVMArgVtypeInReg: {
3440 LLVMValueRef regs [2];
3442 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3446 if (!addresses [ins->dreg])
3447 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3449 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3450 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3451 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3452 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3455 case LLVMArgVtypeByVal:
3456 if (!addresses [call->inst.dreg])
3457 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3458 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3460 case LLVMArgFpStruct:
3461 if (!addresses [call->inst.dreg])
3462 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3463 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3465 case LLVMArgVtypeAsScalar:
3466 if (!addresses [call->inst.dreg])
3467 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3468 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3470 case LLVMArgVtypeRetAddr:
3471 case LLVMArgVtypeByRef:
3472 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3473 /* Some opcodes like STOREX_MEMBASE access these by value */
3474 g_assert (addresses [call->inst.dreg]);
3475 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3478 case LLVMArgScalarRetAddr:
3479 /* Normal scalar returned using a vtype return argument */
3480 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3482 case LLVMArgGsharedvtVariable:
3484 case LLVMArgGsharedvtFixed:
3485 case LLVMArgGsharedvtFixedVtype:
3486 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3489 if (sig->ret->type != MONO_TYPE_VOID)
3490 /* If the method returns an unsigned value, need to zext it */
3491 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));
3495 *builder_ref = ctx->builder;
3499 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3501 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3502 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3504 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3507 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3509 if (ctx->cfg->compile_aot) {
3510 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3512 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3513 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3514 mono_memory_barrier ();
3517 ctx->module->rethrow = callee;
3519 ctx->module->throw_icall = callee;
3523 LLVMValueRef args [2];
3525 args [0] = convert (ctx, exc, exc_type);
3526 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3528 LLVMBuildUnreachable (ctx->builder);
3530 ctx->builder = create_builder (ctx);
3534 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3536 MonoMethodSignature *throw_sig;
3537 LLVMValueRef callee, arg;
3538 const char *icall_name;
3540 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3541 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3544 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3545 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3546 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3547 if (ctx->cfg->compile_aot) {
3548 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3550 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3554 * LLVM doesn't push the exception argument, so we need a different
3557 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3559 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3563 mono_memory_barrier ();
3565 ctx->module->rethrow = callee;
3567 ctx->module->throw_icall = callee;
3569 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3570 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3574 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3576 const char *icall_name = "mono_llvm_resume_exception";
3577 LLVMValueRef callee = ctx->module->resume_eh;
3579 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3582 if (ctx->cfg->compile_aot) {
3583 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3585 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3586 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3587 mono_memory_barrier ();
3589 ctx->module->resume_eh = callee;
3593 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3595 LLVMBuildUnreachable (ctx->builder);
3597 ctx->builder = create_builder (ctx);
3601 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3603 const char *icall_name = "mono_llvm_clear_exception";
3605 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3606 LLVMValueRef callee = NULL;
3609 if (ctx->cfg->compile_aot) {
3610 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3612 // FIXME: This is broken.
3613 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3617 g_assert (builder && callee);
3619 return LLVMBuildCall (builder, callee, NULL, 0, "");
3623 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3625 const char *icall_name = "mono_llvm_load_exception";
3627 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3628 LLVMValueRef callee = NULL;
3631 if (ctx->cfg->compile_aot) {
3632 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3634 // FIXME: This is broken.
3635 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3639 g_assert (builder && callee);
3641 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3646 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3648 const char *icall_name = "mono_llvm_match_exception";
3650 ctx->builder = builder;
3652 const int num_args = 5;
3653 LLVMValueRef args [num_args];
3654 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3655 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3656 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3657 if (ctx->cfg->rgctx_var) {
3658 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3659 g_assert (rgctx_alloc);
3660 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3662 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3665 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3667 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3669 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3670 LLVMValueRef callee = ctx->module->match_exc;
3673 if (ctx->cfg->compile_aot) {
3674 ctx->builder = builder;
3675 // get_callee expects ctx->builder to be the emitting builder
3676 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3678 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3679 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3680 ctx->module->match_exc = callee;
3681 mono_memory_barrier ();
3685 g_assert (builder && callee);
3687 g_assert (ctx->ex_var);
3689 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3692 // FIXME: This won't work because the code-finding makes this
3694 /*#define MONO_PERSONALITY_DEBUG*/
3696 #ifdef MONO_PERSONALITY_DEBUG
3697 static const gboolean use_debug_personality = TRUE;
3698 static const char *default_personality_name = "mono_debug_personality";
3700 static const gboolean use_debug_personality = FALSE;
3701 static const char *default_personality_name = "__gxx_personality_v0";
3705 default_cpp_lpad_exc_signature (void)
3707 static gboolean inited = FALSE;
3708 static LLVMTypeRef sig;
3711 LLVMTypeRef signature [2];
3712 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3713 signature [1] = LLVMInt32Type ();
3714 sig = LLVMStructType (signature, 2, FALSE);
3722 get_mono_personality (EmitContext *ctx)
3724 LLVMValueRef personality = NULL;
3725 static gint32 mapping_inited = FALSE;
3726 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3728 if (!use_debug_personality) {
3729 if (ctx->cfg->compile_aot) {
3730 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3731 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3732 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3733 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3736 if (ctx->cfg->compile_aot) {
3737 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3739 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3740 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3741 mono_memory_barrier ();
3745 g_assert (personality);
3749 static LLVMBasicBlockRef
3750 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3752 MonoCompile *cfg = ctx->cfg;
3753 LLVMBuilderRef old_builder = ctx->builder;
3754 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3756 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3757 ctx->builder = lpadBuilder;
3759 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3760 g_assert (handler_bb);
3762 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3763 LLVMValueRef personality = get_mono_personality (ctx);
3764 g_assert (personality);
3766 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3767 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3769 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3770 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3771 g_assert (landing_pad);
3773 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3774 LLVMAddClause (landing_pad, cast);
3776 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3777 LLVMBuilderRef resume_builder = create_builder (ctx);
3778 ctx->builder = resume_builder;
3779 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3781 emit_resume_eh (ctx, handler_bb);
3784 ctx->builder = lpadBuilder;
3785 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3787 gboolean finally_only = TRUE;
3789 MonoExceptionClause *group_cursor = group_start;
3791 for (int i = 0; i < group_size; i ++) {
3792 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3793 finally_only = FALSE;
3799 // Handle landing pad inlining
3801 if (!finally_only) {
3802 // So at each level of the exception stack we will match the exception again.
3803 // During that match, we need to compare against the handler types for the current
3804 // protected region. We send the try start and end so that we can only check against
3805 // handlers for this lexical protected region.
3806 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3808 // if returns -1, resume
3809 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3811 // else move to that target bb
3812 for (int i=0; i < group_size; i++) {
3813 MonoExceptionClause *clause = group_start + i;
3814 int clause_index = clause - cfg->header->clauses;
3815 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3816 g_assert (handler_bb);
3817 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3818 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3821 int clause_index = group_start - cfg->header->clauses;
3822 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3823 g_assert (finally_bb);
3825 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3828 ctx->builder = old_builder;
3835 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3837 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3838 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3840 // Make exception available to catch blocks
3841 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3842 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3844 g_assert (ctx->ex_var);
3845 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3847 if (bb->in_scount == 1) {
3848 MonoInst *exvar = bb->in_stack [0];
3849 g_assert (!ctx->values [exvar->dreg]);
3850 g_assert (ctx->ex_var);
3851 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3852 emit_volatile_store (ctx, exvar->dreg);
3855 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3858 LLVMBuilderRef handler_builder = create_builder (ctx);
3859 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3860 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3862 // Make the handler code end with a jump to cbb
3863 LLVMBuildBr (handler_builder, cbb);
3867 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3869 MonoCompile *cfg = ctx->cfg;
3870 LLVMValueRef *values = ctx->values;
3871 LLVMModuleRef lmodule = ctx->lmodule;
3872 BBInfo *bblocks = ctx->bblocks;
3874 LLVMValueRef personality;
3875 LLVMValueRef landing_pad;
3876 LLVMBasicBlockRef target_bb;
3878 static gint32 mapping_inited;
3879 static int ti_generator;
3882 LLVMValueRef type_info;
3886 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3888 if (cfg->compile_aot) {
3889 /* Use a dummy personality function */
3890 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3891 g_assert (personality);
3893 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3894 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3895 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3898 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3900 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3903 * Create the type info
3905 sprintf (ti_name, "type_info_%d", ti_generator);
3908 if (cfg->compile_aot) {
3909 /* decode_eh_frame () in aot-runtime.c will decode this */
3910 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3911 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3914 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3916 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3919 * After the cfg mempool is freed, the type info will point to stale memory,
3920 * but this is not a problem, since we decode it once in exception_cb during
3923 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3924 *(gint32*)ti = clause_index;
3926 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3928 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3932 LLVMTypeRef members [2], ret_type;
3934 members [0] = i8ptr;
3935 members [1] = LLVMInt32Type ();
3936 ret_type = LLVMStructType (members, 2, FALSE);
3938 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3939 LLVMAddClause (landing_pad, type_info);
3941 /* Store the exception into the exvar */
3943 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3947 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3948 * code expects control to be transferred to this landing pad even in the
3949 * presence of nested clauses. The landing pad needs to branch to the landing
3950 * pads belonging to nested clauses based on the selector value returned by
3951 * the landing pad instruction, which is passed to the landing pad in a
3952 * register by the EH code.
3954 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3955 g_assert (target_bb);
3958 * Branch to the correct landing pad
3960 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3961 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3963 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3964 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3965 MonoBasicBlock *handler_bb;
3967 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3968 g_assert (handler_bb);
3970 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3971 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3974 /* Start a new bblock which CALL_HANDLER can branch to */
3975 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3977 ctx->builder = builder = create_builder (ctx);
3978 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3980 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3982 /* Store the exception into the IL level exvar */
3983 if (bb->in_scount == 1) {
3984 g_assert (bb->in_scount == 1);
3985 exvar = bb->in_stack [0];
3987 // FIXME: This is shared with filter clauses ?
3988 g_assert (!values [exvar->dreg]);
3990 g_assert (ctx->ex_var);
3991 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3992 emit_volatile_store (ctx, exvar->dreg);
3998 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4000 MonoCompile *cfg = ctx->cfg;
4001 MonoMethodSignature *sig = ctx->sig;
4002 LLVMValueRef method = ctx->lmethod;
4003 LLVMValueRef *values = ctx->values;
4004 LLVMValueRef *addresses = ctx->addresses;
4005 LLVMCallInfo *linfo = ctx->linfo;
4006 LLVMModuleRef lmodule = ctx->lmodule;
4007 BBInfo *bblocks = ctx->bblocks;
4009 LLVMBasicBlockRef cbb;
4010 LLVMBuilderRef builder, starting_builder;
4011 gboolean has_terminator;
4013 LLVMValueRef lhs, rhs;
4016 cbb = get_end_bb (ctx, bb);
4018 builder = create_builder (ctx);
4019 ctx->builder = builder;
4020 LLVMPositionBuilderAtEnd (builder, cbb);
4025 if (bb->flags & BB_EXCEPTION_HANDLER) {
4026 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4027 set_failure (ctx, "handler without invokes");
4032 emit_llvmonly_handler_start (ctx, bb, cbb);
4034 emit_handler_start (ctx, bb, builder);
4037 builder = ctx->builder;
4040 has_terminator = FALSE;
4041 starting_builder = builder;
4042 for (ins = bb->code; ins; ins = ins->next) {
4043 const char *spec = LLVM_INS_INFO (ins->opcode);
4045 char dname_buf [128];
4047 emit_dbg_loc (ctx, builder, ins->cil_code);
4052 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4053 * Start a new bblock. If the llvm optimization passes merge these, we
4054 * can work around that by doing a volatile load + cond branch from
4055 * localloc-ed memory.
4057 //set_failure (ctx, "basic block too long");
4058 cbb = gen_bb (ctx, "CONT_LONG_BB");
4059 LLVMBuildBr (ctx->builder, cbb);
4060 ctx->builder = builder = create_builder (ctx);
4061 LLVMPositionBuilderAtEnd (builder, cbb);
4062 ctx->bblocks [bb->block_num].end_bblock = cbb;
4067 /* There could be instructions after a terminator, skip them */
4070 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4071 sprintf (dname_buf, "t%d", ins->dreg);
4075 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4076 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4078 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4079 lhs = emit_volatile_load (ctx, ins->sreg1);
4081 /* It is ok for SETRET to have an uninitialized argument */
4082 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4083 set_failure (ctx, "sreg1");
4086 lhs = values [ins->sreg1];
4092 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4093 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4094 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4095 rhs = emit_volatile_load (ctx, ins->sreg2);
4097 if (!values [ins->sreg2]) {
4098 set_failure (ctx, "sreg2");
4101 rhs = values [ins->sreg2];
4107 //mono_print_ins (ins);
4108 switch (ins->opcode) {
4111 case OP_LIVERANGE_START:
4112 case OP_LIVERANGE_END:
4115 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4118 #if SIZEOF_VOID_P == 4
4119 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4121 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4125 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4129 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4131 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4133 case OP_DUMMY_ICONST:
4134 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4136 case OP_DUMMY_I8CONST:
4137 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4139 case OP_DUMMY_R8CONST:
4140 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4143 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4144 LLVMBuildBr (builder, target_bb);
4145 has_terminator = TRUE;
4152 LLVMBasicBlockRef new_bb;
4153 LLVMBuilderRef new_builder;
4155 // The default branch is already handled
4156 // FIXME: Handle it here
4158 /* Start new bblock */
4159 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4160 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4162 lhs = convert (ctx, lhs, LLVMInt32Type ());
4163 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4164 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4165 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4167 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4170 new_builder = create_builder (ctx);
4171 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4172 LLVMBuildUnreachable (new_builder);
4174 has_terminator = TRUE;
4175 g_assert (!ins->next);
4181 switch (linfo->ret.storage) {
4182 case LLVMArgVtypeInReg: {
4183 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4184 LLVMValueRef val, addr, retval;
4187 retval = LLVMGetUndef (ret_type);
4189 if (!addresses [ins->sreg1]) {
4191 * The return type is an LLVM vector type, have to convert between it and the
4192 * real return type which is a struct type.
4194 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4195 /* Convert to 2xi64 first */
4196 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4198 for (i = 0; i < 2; ++i) {
4199 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4200 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4202 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4206 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4207 for (i = 0; i < 2; ++i) {
4208 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4209 LLVMValueRef indexes [2], part_addr;
4211 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4212 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4213 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4215 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4217 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4221 LLVMBuildRet (builder, retval);
4224 case LLVMArgVtypeAsScalar: {
4225 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4226 LLVMValueRef retval;
4228 g_assert (addresses [ins->sreg1]);
4230 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4231 LLVMBuildRet (builder, retval);
4234 case LLVMArgVtypeByVal: {
4235 LLVMValueRef retval;
4237 g_assert (addresses [ins->sreg1]);
4238 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4239 LLVMBuildRet (builder, retval);
4242 case LLVMArgVtypeByRef: {
4243 LLVMBuildRetVoid (builder);
4246 case LLVMArgGsharedvtFixed: {
4247 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4248 /* The return value is in lhs, need to store to the vret argument */
4249 /* sreg1 might not be set */
4251 g_assert (cfg->vret_addr);
4252 g_assert (values [cfg->vret_addr->dreg]);
4253 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4255 LLVMBuildRetVoid (builder);
4258 case LLVMArgGsharedvtFixedVtype: {
4260 LLVMBuildRetVoid (builder);
4263 case LLVMArgGsharedvtVariable: {
4265 LLVMBuildRetVoid (builder);
4268 case LLVMArgVtypeRetAddr: {
4269 LLVMBuildRetVoid (builder);
4272 case LLVMArgScalarRetAddr: {
4273 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4274 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4276 /* sreg1 might not be set */
4278 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4279 LLVMBuildRetVoid (builder);
4282 case LLVMArgFpStruct: {
4283 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4284 LLVMValueRef retval;
4286 g_assert (addresses [ins->sreg1]);
4287 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4288 LLVMBuildRet (builder, retval);
4292 case LLVMArgNormal: {
4293 if (!lhs || ctx->is_dead [ins->sreg1]) {
4295 * The method did not set its return value, probably because it
4296 * ends with a throw.
4299 LLVMBuildRetVoid (builder);
4301 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4303 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4305 has_terminator = TRUE;
4309 g_assert_not_reached ();
4318 case OP_ICOMPARE_IMM:
4319 case OP_LCOMPARE_IMM:
4320 case OP_COMPARE_IMM: {
4322 LLVMValueRef cmp, args [16];
4323 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4325 if (ins->next->opcode == OP_NOP)
4328 if (ins->next->opcode == OP_BR)
4329 /* The comparison result is not needed */
4332 rel = mono_opcode_to_cond (ins->next->opcode);
4334 if (ins->opcode == OP_ICOMPARE_IMM) {
4335 lhs = convert (ctx, lhs, LLVMInt32Type ());
4336 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4338 if (ins->opcode == OP_LCOMPARE_IMM) {
4339 lhs = convert (ctx, lhs, LLVMInt64Type ());
4340 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4342 if (ins->opcode == OP_LCOMPARE) {
4343 lhs = convert (ctx, lhs, LLVMInt64Type ());
4344 rhs = convert (ctx, rhs, LLVMInt64Type ());
4346 if (ins->opcode == OP_ICOMPARE) {
4347 lhs = convert (ctx, lhs, LLVMInt32Type ());
4348 rhs = convert (ctx, rhs, LLVMInt32Type ());
4352 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4353 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4354 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4355 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4358 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4359 if (ins->opcode == OP_FCOMPARE) {
4360 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4361 } else if (ins->opcode == OP_RCOMPARE) {
4362 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4363 } else if (ins->opcode == OP_COMPARE_IMM) {
4364 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4365 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4367 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4368 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4369 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4370 /* The immediate is encoded in two fields */
4371 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4372 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4374 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4377 else if (ins->opcode == OP_COMPARE) {
4378 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4379 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4381 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4383 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4387 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4388 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4391 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4392 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4394 * If the target bb contains PHI instructions, LLVM requires
4395 * two PHI entries for this bblock, while we only generate one.
4396 * So convert this to an unconditional bblock. (bxc #171).
4398 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4400 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4402 has_terminator = TRUE;
4403 } else if (MONO_IS_SETCC (ins->next)) {
4404 sprintf (dname_buf, "t%d", ins->next->dreg);
4406 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4408 /* Add stores for volatile variables */
4409 emit_volatile_store (ctx, ins->next->dreg);
4410 } else if (MONO_IS_COND_EXC (ins->next)) {
4411 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4414 builder = ctx->builder;
4416 set_failure (ctx, "next");
4434 rel = mono_opcode_to_cond (ins->opcode);
4436 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4437 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4448 rel = mono_opcode_to_cond (ins->opcode);
4450 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4451 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4459 gboolean empty = TRUE;
4461 /* Check that all input bblocks really branch to us */
4462 for (i = 0; i < bb->in_count; ++i) {
4463 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4464 ins->inst_phi_args [i + 1] = -1;
4470 /* LLVM doesn't like phi instructions with zero operands */
4471 ctx->is_dead [ins->dreg] = TRUE;
4475 /* Created earlier, insert it now */
4476 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4478 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4479 int sreg1 = ins->inst_phi_args [i + 1];
4483 * Count the number of times the incoming bblock branches to us,
4484 * since llvm requires a separate entry for each.
4486 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4487 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4490 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4491 if (switch_ins->inst_many_bb [j] == bb)
4498 /* Remember for later */
4499 for (j = 0; j < count; ++j) {
4500 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4503 node->in_bb = bb->in_bb [i];
4505 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);
4515 values [ins->dreg] = lhs;
4519 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4522 values [ins->dreg] = lhs;
4524 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4526 * This is added by the spilling pass in case of the JIT,
4527 * but we have to do it ourselves.
4529 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4533 case OP_MOVE_F_TO_I4: {
4534 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4537 case OP_MOVE_I4_TO_F: {
4538 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4541 case OP_MOVE_F_TO_I8: {
4542 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4545 case OP_MOVE_I8_TO_F: {
4546 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4579 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4580 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4582 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4585 builder = ctx->builder;
4587 switch (ins->opcode) {
4590 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4594 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4598 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4602 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4606 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4610 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4614 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4618 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4622 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4626 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4630 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4634 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4638 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4642 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4646 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4649 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4652 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4656 g_assert_not_reached ();
4663 lhs = convert (ctx, lhs, LLVMFloatType ());
4664 rhs = convert (ctx, rhs, LLVMFloatType ());
4665 switch (ins->opcode) {
4667 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4670 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4673 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4676 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4679 g_assert_not_reached ();
4688 case OP_IREM_UN_IMM:
4690 case OP_IDIV_UN_IMM:
4696 case OP_ISHR_UN_IMM:
4706 case OP_LSHR_UN_IMM:
4712 case OP_SHR_UN_IMM: {
4715 if (spec [MONO_INST_SRC1] == 'l') {
4716 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4718 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4721 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4724 builder = ctx->builder;
4726 #if SIZEOF_VOID_P == 4
4727 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4728 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4731 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4732 lhs = convert (ctx, lhs, IntPtrType ());
4733 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4734 switch (ins->opcode) {
4738 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4742 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4747 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4751 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4753 case OP_IDIV_UN_IMM:
4754 case OP_LDIV_UN_IMM:
4755 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4759 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4761 case OP_IREM_UN_IMM:
4762 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4767 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4771 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4775 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4780 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4785 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4787 case OP_ISHR_UN_IMM:
4788 /* This is used to implement conv.u4, so the lhs could be an i8 */
4789 lhs = convert (ctx, lhs, LLVMInt32Type ());
4790 imm = convert (ctx, imm, LLVMInt32Type ());
4791 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4793 case OP_LSHR_UN_IMM:
4795 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4798 g_assert_not_reached ();
4803 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4806 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4809 lhs = convert (ctx, lhs, LLVMDoubleType ());
4810 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4813 lhs = convert (ctx, lhs, LLVMFloatType ());
4814 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4817 guint32 v = 0xffffffff;
4818 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4822 guint64 v = 0xffffffffffffffffLL;
4823 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4826 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4828 LLVMValueRef v1, v2;
4830 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4831 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4832 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4837 case OP_ICONV_TO_I1:
4838 case OP_ICONV_TO_I2:
4839 case OP_ICONV_TO_I4:
4840 case OP_ICONV_TO_U1:
4841 case OP_ICONV_TO_U2:
4842 case OP_ICONV_TO_U4:
4843 case OP_LCONV_TO_I1:
4844 case OP_LCONV_TO_I2:
4845 case OP_LCONV_TO_U1:
4846 case OP_LCONV_TO_U2:
4847 case OP_LCONV_TO_U4: {
4850 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);
4852 /* Have to do two casts since our vregs have type int */
4853 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4855 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4857 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4860 case OP_ICONV_TO_I8:
4861 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4863 case OP_ICONV_TO_U8:
4864 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4866 case OP_FCONV_TO_I4:
4867 case OP_RCONV_TO_I4:
4868 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4870 case OP_FCONV_TO_I1:
4871 case OP_RCONV_TO_I1:
4872 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4874 case OP_FCONV_TO_U1:
4875 case OP_RCONV_TO_U1:
4876 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4878 case OP_FCONV_TO_I2:
4879 case OP_RCONV_TO_I2:
4880 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4882 case OP_FCONV_TO_U2:
4883 case OP_RCONV_TO_U2:
4884 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4886 case OP_RCONV_TO_U4:
4887 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4889 case OP_FCONV_TO_I8:
4890 case OP_RCONV_TO_I8:
4891 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4894 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4896 case OP_ICONV_TO_R8:
4897 case OP_LCONV_TO_R8:
4898 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4900 case OP_ICONV_TO_R_UN:
4901 case OP_LCONV_TO_R_UN:
4902 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4904 #if SIZEOF_VOID_P == 4
4907 case OP_LCONV_TO_I4:
4908 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4910 case OP_ICONV_TO_R4:
4911 case OP_LCONV_TO_R4:
4912 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4914 values [ins->dreg] = v;
4916 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4918 case OP_FCONV_TO_R4:
4919 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4921 values [ins->dreg] = v;
4923 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4925 case OP_RCONV_TO_R8:
4926 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4928 case OP_RCONV_TO_R4:
4929 values [ins->dreg] = lhs;
4932 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4935 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4938 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4940 case OP_LOCALLOC_IMM: {
4943 guint32 size = ins->inst_imm;
4944 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4946 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4948 if (ins->flags & MONO_INST_INIT) {
4949 LLVMValueRef args [5];
4952 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4953 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4954 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4955 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4956 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4959 values [ins->dreg] = v;
4963 LLVMValueRef v, size;
4965 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), "");
4967 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4969 if (ins->flags & MONO_INST_INIT) {
4970 LLVMValueRef args [5];
4973 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4975 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4976 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4977 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4979 values [ins->dreg] = v;
4983 case OP_LOADI1_MEMBASE:
4984 case OP_LOADU1_MEMBASE:
4985 case OP_LOADI2_MEMBASE:
4986 case OP_LOADU2_MEMBASE:
4987 case OP_LOADI4_MEMBASE:
4988 case OP_LOADU4_MEMBASE:
4989 case OP_LOADI8_MEMBASE:
4990 case OP_LOADR4_MEMBASE:
4991 case OP_LOADR8_MEMBASE:
4992 case OP_LOAD_MEMBASE:
5000 LLVMValueRef base, index, addr;
5002 gboolean sext = FALSE, zext = FALSE;
5003 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5005 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5010 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)) {
5011 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5016 if (ins->inst_offset == 0) {
5018 } else if (ins->inst_offset % size != 0) {
5019 /* Unaligned load */
5020 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5021 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5023 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5024 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5028 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5030 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5032 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5034 * These will signal LLVM that these loads do not alias any stores, and
5035 * they can't fail, allowing them to be hoisted out of loops.
5037 set_invariant_load_flag (values [ins->dreg]);
5038 #if LLVM_API_VERSION < 100
5039 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5044 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5046 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5047 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5048 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5052 case OP_STOREI1_MEMBASE_REG:
5053 case OP_STOREI2_MEMBASE_REG:
5054 case OP_STOREI4_MEMBASE_REG:
5055 case OP_STOREI8_MEMBASE_REG:
5056 case OP_STORER4_MEMBASE_REG:
5057 case OP_STORER8_MEMBASE_REG:
5058 case OP_STORE_MEMBASE_REG: {
5060 LLVMValueRef index, addr;
5062 gboolean sext = FALSE, zext = FALSE;
5063 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5065 if (!values [ins->inst_destbasereg]) {
5066 set_failure (ctx, "inst_destbasereg");
5070 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5072 if (ins->inst_offset % size != 0) {
5073 /* Unaligned store */
5074 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5075 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5077 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5078 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5080 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5084 case OP_STOREI1_MEMBASE_IMM:
5085 case OP_STOREI2_MEMBASE_IMM:
5086 case OP_STOREI4_MEMBASE_IMM:
5087 case OP_STOREI8_MEMBASE_IMM:
5088 case OP_STORE_MEMBASE_IMM: {
5090 LLVMValueRef index, addr;
5092 gboolean sext = FALSE, zext = FALSE;
5093 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5095 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5097 if (ins->inst_offset % size != 0) {
5098 /* Unaligned store */
5099 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5100 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5102 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5103 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5105 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5110 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5112 case OP_OUTARG_VTRETADDR:
5120 case OP_VOIDCALL_MEMBASE:
5121 case OP_CALL_MEMBASE:
5122 case OP_LCALL_MEMBASE:
5123 case OP_FCALL_MEMBASE:
5124 case OP_RCALL_MEMBASE:
5125 case OP_VCALL_MEMBASE:
5126 case OP_VOIDCALL_REG:
5131 case OP_VCALL_REG: {
5132 process_call (ctx, bb, &builder, ins);
5137 LLVMValueRef indexes [2];
5138 MonoJumpInfo *tmp_ji, *ji;
5139 LLVMValueRef got_entry_addr;
5143 * FIXME: Can't allocate from the cfg mempool since that is freed if
5144 * the LLVM compile fails.
5146 tmp_ji = g_new0 (MonoJumpInfo, 1);
5147 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5148 tmp_ji->data.target = ins->inst_p0;
5150 ji = mono_aot_patch_info_dup (tmp_ji);
5153 ji->next = cfg->patch_info;
5154 cfg->patch_info = ji;
5156 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5157 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5158 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5159 if (!mono_aot_is_shared_got_offset (got_offset)) {
5160 //mono_print_ji (ji);
5162 ctx->has_got_access = TRUE;
5165 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5166 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5167 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5169 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5170 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5172 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5173 if (!cfg->llvm_only)
5174 set_invariant_load_flag (values [ins->dreg]);
5177 case OP_NOT_REACHED:
5178 LLVMBuildUnreachable (builder);
5179 has_terminator = TRUE;
5180 g_assert (bb->block_num < cfg->max_block_num);
5181 ctx->unreachable [bb->block_num] = TRUE;
5182 /* Might have instructions after this */
5184 MonoInst *next = ins->next;
5186 * FIXME: If later code uses the regs defined by these instructions,
5187 * compilation will fail.
5189 MONO_DELETE_INS (bb, next);
5193 MonoInst *var = ins->inst_i0;
5195 if (var->opcode == OP_VTARG_ADDR) {
5196 /* The variable contains the vtype address */
5197 values [ins->dreg] = values [var->dreg];
5198 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5199 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5201 values [ins->dreg] = addresses [var->dreg];
5206 LLVMValueRef args [1];
5208 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5209 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5213 LLVMValueRef args [1];
5215 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5216 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5220 LLVMValueRef args [1];
5222 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5223 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5227 LLVMValueRef args [1];
5229 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5230 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5244 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5245 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5247 switch (ins->opcode) {
5250 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5254 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5258 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5262 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5265 g_assert_not_reached ();
5268 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5271 case OP_ATOMIC_EXCHANGE_I4:
5272 case OP_ATOMIC_EXCHANGE_I8: {
5273 LLVMValueRef args [2];
5276 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5277 t = LLVMInt32Type ();
5279 t = LLVMInt64Type ();
5281 g_assert (ins->inst_offset == 0);
5283 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5284 args [1] = convert (ctx, rhs, t);
5286 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5289 case OP_ATOMIC_ADD_I4:
5290 case OP_ATOMIC_ADD_I8: {
5291 LLVMValueRef args [2];
5294 if (ins->opcode == OP_ATOMIC_ADD_I4)
5295 t = LLVMInt32Type ();
5297 t = LLVMInt64Type ();
5299 g_assert (ins->inst_offset == 0);
5301 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5302 args [1] = convert (ctx, rhs, t);
5303 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5306 case OP_ATOMIC_CAS_I4:
5307 case OP_ATOMIC_CAS_I8: {
5308 LLVMValueRef args [3], val;
5311 if (ins->opcode == OP_ATOMIC_CAS_I4)
5312 t = LLVMInt32Type ();
5314 t = LLVMInt64Type ();
5316 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5318 args [1] = convert (ctx, values [ins->sreg3], t);
5320 args [2] = convert (ctx, values [ins->sreg2], t);
5321 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5322 /* cmpxchg returns a pair */
5323 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5326 case OP_MEMORY_BARRIER: {
5327 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5330 case OP_ATOMIC_LOAD_I1:
5331 case OP_ATOMIC_LOAD_I2:
5332 case OP_ATOMIC_LOAD_I4:
5333 case OP_ATOMIC_LOAD_I8:
5334 case OP_ATOMIC_LOAD_U1:
5335 case OP_ATOMIC_LOAD_U2:
5336 case OP_ATOMIC_LOAD_U4:
5337 case OP_ATOMIC_LOAD_U8:
5338 case OP_ATOMIC_LOAD_R4:
5339 case OP_ATOMIC_LOAD_R8: {
5340 set_failure (ctx, "atomic mono.load intrinsic");
5344 gboolean sext, zext;
5346 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5347 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5348 LLVMValueRef index, addr;
5350 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5355 if (ins->inst_offset != 0) {
5356 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5357 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5362 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5364 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5367 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5369 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5373 case OP_ATOMIC_STORE_I1:
5374 case OP_ATOMIC_STORE_I2:
5375 case OP_ATOMIC_STORE_I4:
5376 case OP_ATOMIC_STORE_I8:
5377 case OP_ATOMIC_STORE_U1:
5378 case OP_ATOMIC_STORE_U2:
5379 case OP_ATOMIC_STORE_U4:
5380 case OP_ATOMIC_STORE_U8:
5381 case OP_ATOMIC_STORE_R4:
5382 case OP_ATOMIC_STORE_R8: {
5383 set_failure (ctx, "atomic mono.store intrinsic");
5387 gboolean sext, zext;
5389 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5390 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5391 LLVMValueRef index, addr, value;
5393 if (!values [ins->inst_destbasereg]) {
5394 set_failure (ctx, "inst_destbasereg");
5398 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5400 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5401 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5402 value = convert (ctx, values [ins->sreg1], t);
5404 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5408 case OP_RELAXED_NOP: {
5409 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5410 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5417 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5419 // 257 == FS segment register
5420 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5422 // 256 == GS segment register
5423 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5426 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5427 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5428 /* See mono_amd64_emit_tls_get () */
5429 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5431 // 256 == GS segment register
5432 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5433 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5435 set_failure (ctx, "opcode tls-get");
5441 case OP_TLS_GET_REG: {
5442 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5443 /* See emit_tls_get_reg () */
5444 // 256 == GS segment register
5445 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5446 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5448 set_failure (ctx, "opcode tls-get");
5454 case OP_TLS_SET_REG: {
5455 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5456 /* See emit_tls_get_reg () */
5457 // 256 == GS segment register
5458 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5459 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5461 set_failure (ctx, "opcode tls-set-reg");
5471 case OP_IADD_OVF_UN:
5473 case OP_ISUB_OVF_UN:
5475 case OP_IMUL_OVF_UN:
5476 #if SIZEOF_VOID_P == 8
5478 case OP_LADD_OVF_UN:
5480 case OP_LSUB_OVF_UN:
5482 case OP_LMUL_OVF_UN:
5485 LLVMValueRef args [2], val, ovf, func;
5487 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5488 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5489 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5491 val = LLVMBuildCall (builder, func, args, 2, "");
5492 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5493 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5494 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5497 builder = ctx->builder;
5503 * We currently model them using arrays. Promotion to local vregs is
5504 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5505 * so we always have an entry in cfg->varinfo for them.
5506 * FIXME: Is this needed ?
5509 MonoClass *klass = ins->klass;
5510 LLVMValueRef args [5];
5514 set_failure (ctx, "!klass");
5518 if (!addresses [ins->dreg])
5519 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5520 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5521 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5522 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5524 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5525 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5526 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5529 case OP_DUMMY_VZERO:
5532 case OP_STOREV_MEMBASE:
5533 case OP_LOADV_MEMBASE:
5535 MonoClass *klass = ins->klass;
5536 LLVMValueRef src = NULL, dst, args [5];
5537 gboolean done = FALSE;
5541 set_failure (ctx, "!klass");
5545 if (mini_is_gsharedvt_klass (klass)) {
5547 set_failure (ctx, "gsharedvt");
5551 switch (ins->opcode) {
5552 case OP_STOREV_MEMBASE:
5553 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5554 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5555 /* Decomposed earlier */
5556 g_assert_not_reached ();
5559 if (!addresses [ins->sreg1]) {
5561 g_assert (values [ins->sreg1]);
5562 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));
5563 LLVMBuildStore (builder, values [ins->sreg1], dst);
5566 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5567 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5570 case OP_LOADV_MEMBASE:
5571 if (!addresses [ins->dreg])
5572 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5573 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5574 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5577 if (!addresses [ins->sreg1])
5578 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5579 if (!addresses [ins->dreg])
5580 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5581 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5582 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5585 g_assert_not_reached ();
5595 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5596 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5598 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5599 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5600 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5603 case OP_LLVM_OUTARG_VT: {
5604 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5605 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5607 if (ainfo->storage == LLVMArgScalarByRef) {
5608 LLVMTypeRef argtype;
5609 LLVMValueRef loc, v;
5611 argtype = type_to_llvm_arg_type (ctx, t);
5612 loc = build_alloca_llvm_type (ctx, argtype, 0);
5613 v = convert (ctx, values [ins->sreg1], argtype);
5614 LLVMBuildStore (ctx->builder, v, loc);
5615 addresses [ins->dreg] = loc;
5616 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5617 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5619 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5620 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5622 g_assert (addresses [ins->sreg1]);
5623 addresses [ins->dreg] = addresses [ins->sreg1];
5625 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5626 if (!addresses [ins->sreg1]) {
5627 addresses [ins->sreg1] = build_alloca (ctx, t);
5628 g_assert (values [ins->sreg1]);
5630 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5631 addresses [ins->dreg] = addresses [ins->sreg1];
5633 if (!addresses [ins->sreg1]) {
5634 addresses [ins->sreg1] = build_alloca (ctx, t);
5635 g_assert (values [ins->sreg1]);
5636 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5638 addresses [ins->dreg] = addresses [ins->sreg1];
5646 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5648 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5651 case OP_LOADX_MEMBASE: {
5652 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5655 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5656 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5659 case OP_STOREX_MEMBASE: {
5660 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5663 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5664 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5671 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5675 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5681 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5685 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5689 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5693 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5696 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5699 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5702 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5706 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5717 LLVMValueRef v = NULL;
5719 switch (ins->opcode) {
5724 t = LLVMVectorType (LLVMInt32Type (), 4);
5725 rt = LLVMVectorType (LLVMFloatType (), 4);
5731 t = LLVMVectorType (LLVMInt64Type (), 2);
5732 rt = LLVMVectorType (LLVMDoubleType (), 2);
5735 t = LLVMInt32Type ();
5736 rt = LLVMInt32Type ();
5737 g_assert_not_reached ();
5740 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5741 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5742 switch (ins->opcode) {
5745 v = LLVMBuildAnd (builder, lhs, rhs, "");
5749 v = LLVMBuildOr (builder, lhs, rhs, "");
5753 v = LLVMBuildXor (builder, lhs, rhs, "");
5757 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5760 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5784 case OP_PADDB_SAT_UN:
5785 case OP_PADDW_SAT_UN:
5786 case OP_PSUBB_SAT_UN:
5787 case OP_PSUBW_SAT_UN:
5795 case OP_PMULW_HIGH_UN: {
5796 LLVMValueRef args [2];
5801 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5808 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5812 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5820 case OP_EXTRACTX_U2:
5822 case OP_EXTRACT_U1: {
5824 gboolean zext = FALSE;
5826 t = simd_op_to_llvm_type (ins->opcode);
5828 switch (ins->opcode) {
5836 case OP_EXTRACTX_U2:
5841 t = LLVMInt32Type ();
5842 g_assert_not_reached ();
5845 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5846 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5848 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5857 case OP_EXPAND_R8: {
5858 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5859 LLVMValueRef mask [16], v;
5862 for (i = 0; i < 16; ++i)
5863 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5865 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5867 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5868 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5873 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5876 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5879 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5882 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5885 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5888 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5899 case OP_EXTRACT_MASK:
5906 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5908 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5914 LLVMValueRef args [3];
5918 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5920 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5925 /* This is only used for implementing shifts by non-immediate */
5926 values [ins->dreg] = lhs;
5937 LLVMValueRef args [3];
5940 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5942 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5953 case OP_PSHLQ_REG: {
5954 LLVMValueRef args [3];
5957 args [1] = values [ins->sreg2];
5959 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5966 case OP_PSHUFLEW_LOW:
5967 case OP_PSHUFLEW_HIGH: {
5969 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5970 int i, mask_size = 0;
5971 int imask = ins->inst_c0;
5973 /* Convert the x86 shuffle mask to LLVM's */
5974 switch (ins->opcode) {
5977 mask [0] = ((imask >> 0) & 3);
5978 mask [1] = ((imask >> 2) & 3);
5979 mask [2] = ((imask >> 4) & 3) + 4;
5980 mask [3] = ((imask >> 6) & 3) + 4;
5981 v1 = values [ins->sreg1];
5982 v2 = values [ins->sreg2];
5986 mask [0] = ((imask >> 0) & 1);
5987 mask [1] = ((imask >> 1) & 1) + 2;
5988 v1 = values [ins->sreg1];
5989 v2 = values [ins->sreg2];
5991 case OP_PSHUFLEW_LOW:
5993 mask [0] = ((imask >> 0) & 3);
5994 mask [1] = ((imask >> 2) & 3);
5995 mask [2] = ((imask >> 4) & 3);
5996 mask [3] = ((imask >> 6) & 3);
6001 v1 = values [ins->sreg1];
6002 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6004 case OP_PSHUFLEW_HIGH:
6010 mask [4] = 4 + ((imask >> 0) & 3);
6011 mask [5] = 4 + ((imask >> 2) & 3);
6012 mask [6] = 4 + ((imask >> 4) & 3);
6013 mask [7] = 4 + ((imask >> 6) & 3);
6014 v1 = values [ins->sreg1];
6015 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6019 mask [0] = ((imask >> 0) & 3);
6020 mask [1] = ((imask >> 2) & 3);
6021 mask [2] = ((imask >> 4) & 3);
6022 mask [3] = ((imask >> 6) & 3);
6023 v1 = values [ins->sreg1];
6024 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6027 g_assert_not_reached ();
6029 for (i = 0; i < mask_size; ++i)
6030 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6032 values [ins->dreg] =
6033 LLVMBuildShuffleVector (builder, v1, v2,
6034 LLVMConstVector (mask_values, mask_size), dname);
6038 case OP_UNPACK_LOWB:
6039 case OP_UNPACK_LOWW:
6040 case OP_UNPACK_LOWD:
6041 case OP_UNPACK_LOWQ:
6042 case OP_UNPACK_LOWPS:
6043 case OP_UNPACK_LOWPD:
6044 case OP_UNPACK_HIGHB:
6045 case OP_UNPACK_HIGHW:
6046 case OP_UNPACK_HIGHD:
6047 case OP_UNPACK_HIGHQ:
6048 case OP_UNPACK_HIGHPS:
6049 case OP_UNPACK_HIGHPD: {
6051 LLVMValueRef mask_values [16];
6052 int i, mask_size = 0;
6053 gboolean low = FALSE;
6055 switch (ins->opcode) {
6056 case OP_UNPACK_LOWB:
6060 case OP_UNPACK_LOWW:
6064 case OP_UNPACK_LOWD:
6065 case OP_UNPACK_LOWPS:
6069 case OP_UNPACK_LOWQ:
6070 case OP_UNPACK_LOWPD:
6074 case OP_UNPACK_HIGHB:
6077 case OP_UNPACK_HIGHW:
6080 case OP_UNPACK_HIGHD:
6081 case OP_UNPACK_HIGHPS:
6084 case OP_UNPACK_HIGHQ:
6085 case OP_UNPACK_HIGHPD:
6089 g_assert_not_reached ();
6093 for (i = 0; i < (mask_size / 2); ++i) {
6095 mask [(i * 2) + 1] = mask_size + i;
6098 for (i = 0; i < (mask_size / 2); ++i) {
6099 mask [(i * 2)] = (mask_size / 2) + i;
6100 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6104 for (i = 0; i < mask_size; ++i)
6105 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6107 values [ins->dreg] =
6108 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6109 LLVMConstVector (mask_values, mask_size), dname);
6114 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6115 LLVMValueRef v, val;
6117 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6118 val = LLVMConstNull (t);
6119 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6120 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6122 values [ins->dreg] = val;
6126 case OP_DUPPS_HIGH: {
6127 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6128 LLVMValueRef v1, v2, val;
6131 if (ins->opcode == OP_DUPPS_LOW) {
6132 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6133 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6135 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6136 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6138 val = LLVMConstNull (t);
6139 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6140 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6141 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6142 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6144 values [ins->dreg] = val;
6154 * EXCEPTION HANDLING
6156 case OP_IMPLICIT_EXCEPTION:
6157 /* This marks a place where an implicit exception can happen */
6158 if (bb->region != -1)
6159 set_failure (ctx, "implicit-exception");
6163 gboolean rethrow = (ins->opcode == OP_RETHROW);
6164 if (ctx->llvm_only) {
6165 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6166 has_terminator = TRUE;
6167 ctx->unreachable [bb->block_num] = TRUE;
6169 emit_throw (ctx, bb, rethrow, lhs);
6170 builder = ctx->builder;
6174 case OP_CALL_HANDLER: {
6176 * We don't 'call' handlers, but instead simply branch to them.
6177 * The code generated by ENDFINALLY will branch back to us.
6179 LLVMBasicBlockRef noex_bb;
6181 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6183 bb_list = info->call_handler_return_bbs;
6186 * Set the indicator variable for the finally clause.
6188 lhs = info->finally_ind;
6190 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6192 /* Branch to the finally clause */
6193 LLVMBuildBr (builder, info->call_handler_target_bb);
6195 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6196 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6198 builder = ctx->builder = create_builder (ctx);
6199 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6201 bblocks [bb->block_num].end_bblock = noex_bb;
6204 case OP_START_HANDLER: {
6207 case OP_ENDFINALLY: {
6208 LLVMBasicBlockRef resume_bb;
6209 MonoBasicBlock *handler_bb;
6210 LLVMValueRef val, switch_ins, callee;
6214 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6215 g_assert (handler_bb);
6216 info = &bblocks [handler_bb->block_num];
6217 lhs = info->finally_ind;
6220 bb_list = info->call_handler_return_bbs;
6222 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6224 /* Load the finally variable */
6225 val = LLVMBuildLoad (builder, lhs, "");
6227 /* Reset the variable */
6228 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6230 /* Branch to either resume_bb, or to the bblocks in bb_list */
6231 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6233 * The other targets are added at the end to handle OP_CALL_HANDLER
6234 * opcodes processed later.
6236 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6238 builder = ctx->builder = create_builder (ctx);
6239 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6241 if (ctx->llvm_only) {
6242 emit_resume_eh (ctx, bb);
6244 if (ctx->cfg->compile_aot) {
6245 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6247 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6249 LLVMBuildCall (builder, callee, NULL, 0, "");
6250 LLVMBuildUnreachable (builder);
6253 has_terminator = TRUE;
6256 case OP_IL_SEQ_POINT:
6261 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6262 set_failure (ctx, reason);
6270 /* Convert the value to the type required by phi nodes */
6271 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6272 if (!values [ins->dreg])
6274 values [ins->dreg] = addresses [ins->dreg];
6276 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6279 /* Add stores for volatile variables */
6280 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6281 emit_volatile_store (ctx, ins->dreg);
6287 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6288 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6291 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6292 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6293 LLVMBuildRetVoid (builder);
6296 if (bb == cfg->bb_entry)
6297 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6301 * mono_llvm_check_method_supported:
6303 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6304 * compiling a method twice.
6307 mono_llvm_check_method_supported (MonoCompile *cfg)
6314 if (cfg->method->save_lmf) {
6315 cfg->exception_message = g_strdup ("lmf");
6316 cfg->disable_llvm = TRUE;
6318 if (cfg->disable_llvm)
6322 * Nested clauses where one of the clauses is a finally clause is
6323 * not supported, because LLVM can't figure out the control flow,
6324 * probably because we resume exception handling by calling our
6325 * own function instead of using the 'resume' llvm instruction.
6327 for (i = 0; i < cfg->header->num_clauses; ++i) {
6328 for (j = 0; j < cfg->header->num_clauses; ++j) {
6329 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6330 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6332 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6333 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6334 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6335 cfg->exception_message = g_strdup ("nested clauses");
6336 cfg->disable_llvm = TRUE;
6341 if (cfg->disable_llvm)
6345 if (cfg->method->dynamic) {
6346 cfg->exception_message = g_strdup ("dynamic.");
6347 cfg->disable_llvm = TRUE;
6349 if (cfg->disable_llvm)
6353 static LLVMCallInfo*
6354 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6356 LLVMCallInfo *linfo;
6359 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6363 * Gsharedvt methods have the following calling convention:
6364 * - all arguments are passed by ref, even non generic ones
6365 * - the return value is returned by ref too, using a vret
6366 * argument passed after 'this'.
6368 n = sig->param_count + sig->hasthis;
6369 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6373 linfo->args [pindex ++].storage = LLVMArgNormal;
6375 if (sig->ret->type != MONO_TYPE_VOID) {
6376 if (mini_is_gsharedvt_variable_type (sig->ret))
6377 linfo->ret.storage = LLVMArgGsharedvtVariable;
6378 else if (mini_type_is_vtype (sig->ret))
6379 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6381 linfo->ret.storage = LLVMArgGsharedvtFixed;
6382 linfo->vret_arg_index = pindex;
6384 linfo->ret.storage = LLVMArgNone;
6387 for (i = 0; i < sig->param_count; ++i) {
6388 if (sig->params [i]->byref)
6389 linfo->args [pindex].storage = LLVMArgNormal;
6390 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6391 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6392 else if (mini_type_is_vtype (sig->params [i]))
6393 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6395 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6396 linfo->args [pindex].type = sig->params [i];
6403 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6404 for (i = 0; i < sig->param_count; ++i)
6405 linfo->args [i + sig->hasthis].type = sig->params [i];
6411 emit_method_inner (EmitContext *ctx);
6414 free_ctx (EmitContext *ctx)
6418 g_free (ctx->values);
6419 g_free (ctx->addresses);
6420 g_free (ctx->vreg_types);
6421 g_free (ctx->vreg_cli_types);
6422 g_free (ctx->is_dead);
6423 g_free (ctx->unreachable);
6424 g_ptr_array_free (ctx->phi_values, TRUE);
6425 g_free (ctx->bblocks);
6426 g_hash_table_destroy (ctx->region_to_handler);
6427 g_hash_table_destroy (ctx->clause_to_handler);
6428 g_free (ctx->method_name);
6429 g_ptr_array_free (ctx->bblock_list, TRUE);
6431 for (l = ctx->builders; l; l = l->next) {
6432 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6433 LLVMDisposeBuilder (builder);
6440 * mono_llvm_emit_method:
6442 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6445 mono_llvm_emit_method (MonoCompile *cfg)
6449 gboolean is_linkonce = FALSE;
6452 /* The code below might acquire the loader lock, so use it for global locking */
6453 mono_loader_lock ();
6455 /* Used to communicate with the callbacks */
6456 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6458 ctx = g_new0 (EmitContext, 1);
6460 ctx->mempool = cfg->mempool;
6463 * This maps vregs to the LLVM instruction defining them
6465 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6467 * This maps vregs for volatile variables to the LLVM instruction defining their
6470 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6471 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6472 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6473 ctx->phi_values = g_ptr_array_sized_new (256);
6475 * This signals whenever the vreg was defined by a phi node with no input vars
6476 * (i.e. all its input bblocks end with NOT_REACHABLE).
6478 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6479 /* Whenever the bblock is unreachable */
6480 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6481 ctx->bblock_list = g_ptr_array_sized_new (256);
6483 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6484 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6485 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6486 if (cfg->compile_aot) {
6487 ctx->module = &aot_module;
6491 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6492 * linkage for them. This requires the following:
6493 * - the method needs to have a unique mangled name
6494 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6496 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6498 method_name = mono_aot_get_mangled_method_name (cfg->method);
6500 is_linkonce = FALSE;
6503 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6505 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6509 method_name = mono_aot_get_method_name (cfg);
6510 cfg->llvm_method_name = g_strdup (method_name);
6512 init_jit_module (cfg->domain);
6513 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6514 method_name = mono_method_full_name (cfg->method, TRUE);
6516 ctx->method_name = method_name;
6517 ctx->is_linkonce = is_linkonce;
6519 ctx->lmodule = ctx->module->lmodule;
6520 ctx->llvm_only = ctx->module->llvm_only;
6522 emit_method_inner (ctx);
6524 if (!ctx_ok (ctx)) {
6526 /* Need to add unused phi nodes as they can be referenced by other values */
6527 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6528 LLVMBuilderRef builder;
6530 builder = create_builder (ctx);
6531 LLVMPositionBuilderAtEnd (builder, phi_bb);
6533 for (i = 0; i < ctx->phi_values->len; ++i) {
6534 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6535 if (LLVMGetInstructionParent (v) == NULL)
6536 LLVMInsertIntoBuilder (builder, v);
6539 LLVMDeleteFunction (ctx->lmethod);
6545 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6547 mono_loader_unlock ();
6551 emit_method_inner (EmitContext *ctx)
6553 MonoCompile *cfg = ctx->cfg;
6554 MonoMethodSignature *sig;
6556 LLVMTypeRef method_type;
6557 LLVMValueRef method = NULL;
6558 LLVMValueRef *values = ctx->values;
6559 int i, max_block_num, bb_index;
6560 gboolean last = FALSE;
6561 LLVMCallInfo *linfo;
6562 LLVMModuleRef lmodule = ctx->lmodule;
6564 GPtrArray *bblock_list = ctx->bblock_list;
6565 MonoMethodHeader *header;
6566 MonoExceptionClause *clause;
6569 if (cfg->gsharedvt && !cfg->llvm_only) {
6570 set_failure (ctx, "gsharedvt");
6576 static int count = 0;
6579 if (g_getenv ("LLVM_COUNT")) {
6580 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6581 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6585 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6586 set_failure (ctx, "count");
6593 sig = mono_method_signature (cfg->method);
6596 linfo = get_llvm_call_info (cfg, sig);
6602 linfo->rgctx_arg = TRUE;
6603 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6607 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6608 ctx->lmethod = method;
6610 if (!cfg->llvm_only)
6611 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6612 LLVMSetLinkage (method, LLVMPrivateLinkage);
6614 LLVMAddFunctionAttr (method, LLVMUWTable);
6616 if (cfg->compile_aot) {
6617 LLVMSetLinkage (method, LLVMInternalLinkage);
6618 if (ctx->module->external_symbols) {
6619 LLVMSetLinkage (method, LLVMExternalLinkage);
6620 LLVMSetVisibility (method, LLVMHiddenVisibility);
6622 if (ctx->is_linkonce) {
6623 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6624 LLVMSetVisibility (method, LLVMDefaultVisibility);
6627 LLVMSetLinkage (method, LLVMPrivateLinkage);
6630 if (cfg->method->save_lmf && !cfg->llvm_only) {
6631 set_failure (ctx, "lmf");
6635 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6636 set_failure (ctx, "pinvoke signature");
6640 header = cfg->header;
6641 for (i = 0; i < header->num_clauses; ++i) {
6642 clause = &header->clauses [i];
6643 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6644 set_failure (ctx, "non-finally/catch clause.");
6648 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6649 /* We can't handle inlined methods with clauses */
6650 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6652 if (linfo->rgctx_arg) {
6653 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6654 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6656 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6657 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6658 * CC_X86_64_Mono in X86CallingConv.td.
6660 if (!ctx->llvm_only)
6661 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6662 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6664 ctx->rgctx_arg_pindex = -1;
6666 if (cfg->vret_addr) {
6667 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6668 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6669 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6670 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6671 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6673 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6674 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6675 LLVMSetValueName (param, "vret");
6679 ctx->this_arg_pindex = linfo->this_arg_pindex;
6680 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6681 values [cfg->args [0]->dreg] = ctx->this_arg;
6682 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6685 names = g_new (char *, sig->param_count);
6686 mono_method_get_param_names (cfg->method, (const char **) names);
6688 for (i = 0; i < sig->param_count; ++i) {
6689 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6691 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6694 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6695 name = g_strdup_printf ("dummy_%d_%d", i, j);
6696 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6700 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6701 if (ainfo->storage == LLVMArgScalarByRef) {
6702 if (names [i] && names [i][0] != '\0')
6703 name = g_strdup_printf ("p_arg_%s", names [i]);
6705 name = g_strdup_printf ("p_arg_%d", i);
6706 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6707 if (names [i] && names [i][0] != '\0')
6708 name = g_strdup_printf ("p_arg_%s", names [i]);
6710 name = g_strdup_printf ("p_arg_%d", i);
6712 if (names [i] && names [i][0] != '\0')
6713 name = g_strdup_printf ("arg_%s", names [i]);
6715 name = g_strdup_printf ("arg_%d", i);
6717 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6719 if (ainfo->storage == LLVMArgVtypeByVal)
6720 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6722 if (ainfo->storage == LLVMArgVtypeByRef) {
6724 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6729 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6730 ctx->minfo = mono_debug_lookup_method (cfg->method);
6731 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6735 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6736 max_block_num = MAX (max_block_num, bb->block_num);
6737 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6739 /* Add branches between non-consecutive bblocks */
6740 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6741 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6742 bb->next_bb != bb->last_ins->inst_false_bb) {
6744 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6745 inst->opcode = OP_BR;
6746 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6747 mono_bblock_add_inst (bb, inst);
6752 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6753 * was later optimized away, so clear these flags, and add them back for the still
6754 * present OP_LDADDR instructions.
6756 for (i = 0; i < cfg->next_vreg; ++i) {
6759 ins = get_vreg_to_inst (cfg, i);
6760 if (ins && ins != cfg->rgctx_var)
6761 ins->flags &= ~MONO_INST_INDIRECT;
6765 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6767 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6769 LLVMBuilderRef builder;
6771 char dname_buf[128];
6773 builder = create_builder (ctx);
6775 for (ins = bb->code; ins; ins = ins->next) {
6776 switch (ins->opcode) {
6781 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6786 if (ins->opcode == OP_VPHI) {
6787 /* Treat valuetype PHI nodes as operating on the address itself */
6788 g_assert (ins->klass);
6789 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6793 * Have to precreate these, as they can be referenced by
6794 * earlier instructions.
6796 sprintf (dname_buf, "t%d", ins->dreg);
6798 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6800 if (ins->opcode == OP_VPHI)
6801 ctx->addresses [ins->dreg] = values [ins->dreg];
6803 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6806 * Set the expected type of the incoming arguments since these have
6807 * to have the same type.
6809 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6810 int sreg1 = ins->inst_phi_args [i + 1];
6813 ctx->vreg_types [sreg1] = phi_type;
6818 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6827 * Create an ordering for bblocks, use the depth first order first, then
6828 * put the exception handling bblocks last.
6830 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6831 bb = cfg->bblocks [bb_index];
6832 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6833 g_ptr_array_add (bblock_list, bb);
6834 bblocks [bb->block_num].added = TRUE;
6838 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6839 if (!bblocks [bb->block_num].added)
6840 g_ptr_array_add (bblock_list, bb);
6844 * Second pass: generate code.
6847 LLVMBuilderRef entry_builder = create_builder (ctx);
6848 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6849 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6850 emit_entry_bb (ctx, entry_builder);
6852 // Make landing pads first
6853 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6855 if (ctx->llvm_only) {
6856 size_t group_index = 0;
6857 while (group_index < cfg->header->num_clauses) {
6859 size_t cursor = group_index;
6860 while (cursor < cfg->header->num_clauses &&
6861 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6862 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6867 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6868 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6869 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6871 group_index = cursor;
6875 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6876 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6878 // Prune unreachable mono BBs.
6879 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6882 process_bb (ctx, bb);
6886 g_hash_table_destroy (ctx->exc_meta);
6888 mono_memory_barrier ();
6890 /* Add incoming phi values */
6891 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6892 GSList *l, *ins_list;
6894 ins_list = bblocks [bb->block_num].phi_nodes;
6896 for (l = ins_list; l; l = l->next) {
6897 PhiNode *node = (PhiNode*)l->data;
6898 MonoInst *phi = node->phi;
6899 int sreg1 = node->sreg;
6900 LLVMBasicBlockRef in_bb;
6905 in_bb = get_end_bb (ctx, node->in_bb);
6907 if (ctx->unreachable [node->in_bb->block_num])
6910 if (!values [sreg1]) {
6911 /* Can happen with values in EH clauses */
6912 set_failure (ctx, "incoming phi sreg1");
6916 if (phi->opcode == OP_VPHI) {
6917 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6918 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6920 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6921 set_failure (ctx, "incoming phi arg type mismatch");
6924 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6925 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6930 /* Nullify empty phi instructions */
6931 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6932 GSList *l, *ins_list;
6934 ins_list = bblocks [bb->block_num].phi_nodes;
6936 for (l = ins_list; l; l = l->next) {
6937 PhiNode *node = (PhiNode*)l->data;
6938 MonoInst *phi = node->phi;
6939 LLVMValueRef phi_ins = values [phi->dreg];
6942 /* Already removed */
6945 if (LLVMCountIncoming (phi_ins) == 0) {
6946 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6947 LLVMInstructionEraseFromParent (phi_ins);
6948 values [phi->dreg] = NULL;
6953 /* Create the SWITCH statements for ENDFINALLY instructions */
6954 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6955 BBInfo *info = &bblocks [bb->block_num];
6957 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6958 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6959 GSList *bb_list = info->call_handler_return_bbs;
6961 for (i = 0; i < g_slist_length (bb_list); ++i)
6962 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6966 /* Initialize the method if needed */
6967 if (cfg->compile_aot && ctx->llvm_only) {
6968 // FIXME: Add more shared got entries
6969 ctx->builder = create_builder (ctx);
6970 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6972 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6974 // FIXME: beforefieldinit
6975 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6976 emit_init_method (ctx);
6978 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6982 if (cfg->llvm_only) {
6983 GHashTableIter iter;
6985 GSList *callers, *l, *l2;
6988 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6989 * We can't do this earlier, as it contains llvm instructions which can be
6990 * freed if compilation fails.
6991 * FIXME: Get rid of this when all methods can be llvm compiled.
6993 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6994 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6995 for (l = callers; l; l = l->next) {
6996 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6997 l2 = g_slist_prepend (l2, l->data);
6998 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7003 if (cfg->verbose_level > 1)
7004 mono_llvm_dump_value (method);
7006 if (cfg->compile_aot && !cfg->llvm_only)
7007 mark_as_used (ctx->module, method);
7009 if (cfg->compile_aot && !cfg->llvm_only) {
7010 LLVMValueRef md_args [16];
7011 LLVMValueRef md_node;
7014 method_index = mono_aot_get_method_index (cfg->orig_method);
7015 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7016 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7017 md_node = LLVMMDNode (md_args, 2);
7018 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7019 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7022 if (cfg->compile_aot) {
7023 /* Don't generate native code, keep the LLVM IR */
7024 if (cfg->verbose_level)
7025 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7027 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7028 g_assert (err == 0);
7030 //LLVMVerifyFunction(method, 0);
7031 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7033 if (cfg->verbose_level > 1)
7034 mono_llvm_dump_value (ctx->lmethod);
7036 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7038 /* Set by emit_cb */
7039 g_assert (cfg->code_len);
7042 if (ctx->module->method_to_lmethod)
7043 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7044 if (ctx->module->idx_to_lmethod)
7045 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7047 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7048 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7052 * mono_llvm_create_vars:
7054 * Same as mono_arch_create_vars () for LLVM.
7057 mono_llvm_create_vars (MonoCompile *cfg)
7059 MonoMethodSignature *sig;
7061 sig = mono_method_signature (cfg->method);
7062 if (cfg->gsharedvt && cfg->llvm_only) {
7063 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7064 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7065 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7066 printf ("vret_addr = ");
7067 mono_print_ins (cfg->vret_addr);
7071 mono_arch_create_vars (cfg);
7076 * mono_llvm_emit_call:
7078 * Same as mono_arch_emit_call () for LLVM.
7081 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7084 MonoMethodSignature *sig;
7085 int i, n, stack_size;
7090 sig = call->signature;
7091 n = sig->param_count + sig->hasthis;
7093 call->cinfo = get_llvm_call_info (cfg, sig);
7095 if (cfg->disable_llvm)
7098 if (sig->call_convention == MONO_CALL_VARARG) {
7099 cfg->exception_message = g_strdup ("varargs");
7100 cfg->disable_llvm = TRUE;
7103 for (i = 0; i < n; ++i) {
7106 ainfo = call->cinfo->args + i;
7108 in = call->args [i];
7110 /* Simply remember the arguments */
7111 switch (ainfo->storage) {
7112 case LLVMArgNormal: {
7113 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7116 opcode = mono_type_to_regmove (cfg, t);
7117 if (opcode == OP_FMOVE) {
7118 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7119 ins->dreg = mono_alloc_freg (cfg);
7120 } else if (opcode == OP_LMOVE) {
7121 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7122 ins->dreg = mono_alloc_lreg (cfg);
7123 } else if (opcode == OP_RMOVE) {
7124 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7125 ins->dreg = mono_alloc_freg (cfg);
7127 MONO_INST_NEW (cfg, ins, OP_MOVE);
7128 ins->dreg = mono_alloc_ireg (cfg);
7130 ins->sreg1 = in->dreg;
7133 case LLVMArgVtypeByVal:
7134 case LLVMArgVtypeByRef:
7135 case LLVMArgVtypeInReg:
7136 case LLVMArgVtypeAsScalar:
7137 case LLVMArgScalarByRef:
7138 case LLVMArgAsIArgs:
7139 case LLVMArgAsFpArgs:
7140 case LLVMArgGsharedvtVariable:
7141 case LLVMArgGsharedvtFixed:
7142 case LLVMArgGsharedvtFixedVtype:
7143 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7144 ins->dreg = mono_alloc_ireg (cfg);
7145 ins->sreg1 = in->dreg;
7146 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7147 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7148 ins->inst_vtype = ainfo->type;
7149 ins->klass = mono_class_from_mono_type (ainfo->type);
7152 cfg->exception_message = g_strdup ("ainfo->storage");
7153 cfg->disable_llvm = TRUE;
7157 if (!cfg->disable_llvm) {
7158 MONO_ADD_INS (cfg->cbb, ins);
7159 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7164 static unsigned char*
7165 alloc_cb (LLVMValueRef function, int size)
7169 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7173 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7175 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7180 emitted_cb (LLVMValueRef function, void *start, void *end)
7184 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7186 cfg->code_len = (guint8*)end - (guint8*)start;
7190 exception_cb (void *data)
7193 MonoJitExceptionInfo *ei;
7194 guint32 ei_len, i, j, nested_len, nindex;
7195 gpointer *type_info;
7196 int this_reg, this_offset;
7198 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7202 * data points to a DWARF FDE structure, convert it to our unwind format and
7204 * An alternative would be to save it directly, and modify our unwinder to work
7207 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);
7208 if (cfg->verbose_level > 1)
7209 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7211 /* Count nested clauses */
7213 for (i = 0; i < ei_len; ++i) {
7214 gint32 cindex1 = *(gint32*)type_info [i];
7215 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7217 for (j = 0; j < cfg->header->num_clauses; ++j) {
7219 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7221 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7227 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7228 cfg->llvm_ex_info_len = ei_len + nested_len;
7229 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7230 /* Fill the rest of the information from the type info */
7231 for (i = 0; i < ei_len; ++i) {
7232 gint32 clause_index = *(gint32*)type_info [i];
7233 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7235 cfg->llvm_ex_info [i].flags = clause->flags;
7236 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7237 cfg->llvm_ex_info [i].clause_index = clause_index;
7241 * For nested clauses, the LLVM produced exception info associates the try interval with
7242 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7243 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7244 * and everything else from the nested clause.
7247 for (i = 0; i < ei_len; ++i) {
7248 gint32 cindex1 = *(gint32*)type_info [i];
7249 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7251 for (j = 0; j < cfg->header->num_clauses; ++j) {
7253 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7254 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7256 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7257 /* clause1 is the nested clause */
7258 nested_ei = &cfg->llvm_ex_info [i];
7259 nesting_ei = &cfg->llvm_ex_info [nindex];
7262 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7264 nesting_ei->flags = clause2->flags;
7265 nesting_ei->data.catch_class = clause2->data.catch_class;
7266 nesting_ei->clause_index = cindex2;
7270 g_assert (nindex == ei_len + nested_len);
7271 cfg->llvm_this_reg = this_reg;
7272 cfg->llvm_this_offset = this_offset;
7274 /* type_info [i] is cfg mempool allocated, no need to free it */
7281 dlsym_cb (const char *name, void **symbol)
7287 if (!strcmp (name, "__bzero")) {
7288 *symbol = (void*)bzero;
7290 current = mono_dl_open (NULL, 0, NULL);
7293 err = mono_dl_symbol (current, name, symbol);
7295 mono_dl_close (current);
7297 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7298 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7304 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7306 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7310 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7312 LLVMTypeRef param_types [4];
7314 param_types [0] = param_type1;
7315 param_types [1] = param_type2;
7317 AddFunc (module, name, ret_type, param_types, 2);
7321 add_intrinsics (LLVMModuleRef module)
7323 /* Emit declarations of instrinsics */
7325 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7326 * type doesn't seem to do any locking.
7329 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7331 memset_param_count = 5;
7332 memset_func_name = "llvm.memset.p0i8.i32";
7334 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7338 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7340 memcpy_param_count = 5;
7341 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7343 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7347 LLVMTypeRef params [] = { LLVMDoubleType () };
7349 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7350 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7351 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7353 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7354 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7358 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7359 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7360 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7362 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7363 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7364 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7365 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7366 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7367 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7368 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7372 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7373 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7374 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7376 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7377 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7378 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7379 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7380 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7381 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7384 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7385 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7389 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7391 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7394 /* SSE intrinsics */
7395 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7397 LLVMTypeRef ret_type, arg_types [16];
7400 ret_type = type_to_simd_type (MONO_TYPE_I4);
7401 arg_types [0] = ret_type;
7402 arg_types [1] = ret_type;
7403 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7404 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7406 ret_type = type_to_simd_type (MONO_TYPE_I2);
7407 arg_types [0] = ret_type;
7408 arg_types [1] = ret_type;
7409 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7410 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7411 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7412 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7413 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7414 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7415 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7416 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7417 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7418 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7420 ret_type = type_to_simd_type (MONO_TYPE_I1);
7421 arg_types [0] = ret_type;
7422 arg_types [1] = ret_type;
7423 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7424 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7425 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7426 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7427 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7428 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7429 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7431 ret_type = type_to_simd_type (MONO_TYPE_R8);
7432 arg_types [0] = ret_type;
7433 arg_types [1] = ret_type;
7434 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7435 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7436 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7437 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7438 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7440 ret_type = type_to_simd_type (MONO_TYPE_R4);
7441 arg_types [0] = ret_type;
7442 arg_types [1] = ret_type;
7443 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7444 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7445 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7446 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7447 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7450 ret_type = type_to_simd_type (MONO_TYPE_I1);
7451 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7452 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7453 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7454 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7455 ret_type = type_to_simd_type (MONO_TYPE_I2);
7456 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7457 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7458 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7459 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7462 ret_type = type_to_simd_type (MONO_TYPE_R8);
7463 arg_types [0] = ret_type;
7464 arg_types [1] = ret_type;
7465 arg_types [2] = LLVMInt8Type ();
7466 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7467 ret_type = type_to_simd_type (MONO_TYPE_R4);
7468 arg_types [0] = ret_type;
7469 arg_types [1] = ret_type;
7470 arg_types [2] = LLVMInt8Type ();
7471 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7473 /* Conversion ops */
7474 ret_type = type_to_simd_type (MONO_TYPE_R8);
7475 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7476 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7477 ret_type = type_to_simd_type (MONO_TYPE_R4);
7478 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7479 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7480 ret_type = type_to_simd_type (MONO_TYPE_I4);
7481 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7482 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7483 ret_type = type_to_simd_type (MONO_TYPE_I4);
7484 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7485 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7486 ret_type = type_to_simd_type (MONO_TYPE_R4);
7487 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7488 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7489 ret_type = type_to_simd_type (MONO_TYPE_R8);
7490 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7491 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7493 ret_type = type_to_simd_type (MONO_TYPE_I4);
7494 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7495 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7496 ret_type = type_to_simd_type (MONO_TYPE_I4);
7497 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7498 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7501 ret_type = type_to_simd_type (MONO_TYPE_R8);
7502 arg_types [0] = ret_type;
7503 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7504 ret_type = type_to_simd_type (MONO_TYPE_R4);
7505 arg_types [0] = ret_type;
7506 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7507 ret_type = type_to_simd_type (MONO_TYPE_R4);
7508 arg_types [0] = ret_type;
7509 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7510 ret_type = type_to_simd_type (MONO_TYPE_R4);
7511 arg_types [0] = ret_type;
7512 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7515 ret_type = type_to_simd_type (MONO_TYPE_I2);
7516 arg_types [0] = ret_type;
7517 arg_types [1] = LLVMInt32Type ();
7518 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7519 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7520 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7521 ret_type = type_to_simd_type (MONO_TYPE_I4);
7522 arg_types [0] = ret_type;
7523 arg_types [1] = LLVMInt32Type ();
7524 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7525 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7526 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7527 ret_type = type_to_simd_type (MONO_TYPE_I8);
7528 arg_types [0] = ret_type;
7529 arg_types [1] = LLVMInt32Type ();
7530 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7531 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7534 ret_type = LLVMInt32Type ();
7535 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7536 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7539 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7542 /* Load/Store intrinsics */
7544 LLVMTypeRef arg_types [5];
7548 for (i = 1; i <= 8; i *= 2) {
7549 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7550 arg_types [1] = LLVMInt32Type ();
7551 arg_types [2] = LLVMInt1Type ();
7552 arg_types [3] = LLVMInt32Type ();
7553 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7554 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7556 arg_types [0] = LLVMIntType (i * 8);
7557 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7558 arg_types [2] = LLVMInt32Type ();
7559 arg_types [3] = LLVMInt1Type ();
7560 arg_types [4] = LLVMInt32Type ();
7561 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7562 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7568 add_types (MonoLLVMModule *module)
7570 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7574 mono_llvm_init (void)
7576 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7580 init_jit_module (MonoDomain *domain)
7582 MonoJitICallInfo *info;
7583 MonoJitDomainInfo *dinfo;
7584 MonoLLVMModule *module;
7587 dinfo = domain_jit_info (domain);
7588 if (dinfo->llvm_module)
7591 mono_loader_lock ();
7593 if (dinfo->llvm_module) {
7594 mono_loader_unlock ();
7598 module = g_new0 (MonoLLVMModule, 1);
7600 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7601 module->lmodule = LLVMModuleCreateWithName (name);
7602 module->context = LLVMGetGlobalContext ();
7604 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7606 add_intrinsics (module->lmodule);
7609 module->llvm_types = g_hash_table_new (NULL, NULL);
7611 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7613 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7615 mono_memory_barrier ();
7617 dinfo->llvm_module = module;
7619 mono_loader_unlock ();
7623 mono_llvm_cleanup (void)
7625 MonoLLVMModule *module = &aot_module;
7627 if (module->lmodule)
7628 LLVMDisposeModule (module->lmodule);
7630 if (module->context)
7631 LLVMContextDispose (module->context);
7635 mono_llvm_free_domain_info (MonoDomain *domain)
7637 MonoJitDomainInfo *info = domain_jit_info (domain);
7638 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7644 if (module->llvm_types)
7645 g_hash_table_destroy (module->llvm_types);
7647 mono_llvm_dispose_ee (module->mono_ee);
7649 if (module->bb_names) {
7650 for (i = 0; i < module->bb_names_len; ++i)
7651 g_free (module->bb_names [i]);
7652 g_free (module->bb_names);
7654 //LLVMDisposeModule (module->module);
7658 info->llvm_module = NULL;
7662 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7664 MonoLLVMModule *module = &aot_module;
7666 /* Delete previous module */
7667 if (module->plt_entries)
7668 g_hash_table_destroy (module->plt_entries);
7669 if (module->lmodule)
7670 LLVMDisposeModule (module->lmodule);
7672 memset (module, 0, sizeof (aot_module));
7674 module->lmodule = LLVMModuleCreateWithName ("aot");
7675 module->assembly = assembly;
7676 module->global_prefix = g_strdup (global_prefix);
7677 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7678 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7679 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7680 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7681 module->external_symbols = TRUE;
7682 module->emit_dwarf = emit_dwarf;
7683 module->static_link = static_link;
7684 module->llvm_only = llvm_only;
7685 /* The first few entries are reserved */
7686 module->max_got_offset = 16;
7687 module->context = LLVMContextCreate ();
7690 /* clang ignores our debug info because it has an invalid version */
7691 module->emit_dwarf = FALSE;
7693 add_intrinsics (module->lmodule);
7698 * We couldn't compute the type of the LLVM global representing the got because
7699 * its size is only known after all the methods have been emitted. So create
7700 * a dummy variable, and replace all uses it with the real got variable when
7701 * its size is known in mono_llvm_emit_aot_module ().
7704 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7706 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7707 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7710 /* Add initialization array */
7712 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7714 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7715 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7719 emit_init_icall_wrappers (module);
7721 emit_llvm_code_start (module);
7723 /* Add a dummy personality function */
7724 if (!use_debug_personality) {
7725 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7726 LLVMSetLinkage (personality, LLVMExternalLinkage);
7727 mark_as_used (module, personality);
7730 /* Add a reference to the c++ exception we throw/catch */
7732 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7733 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7734 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7735 mono_llvm_set_is_constant (module->sentinel_exception);
7738 module->llvm_types = g_hash_table_new (NULL, NULL);
7739 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7740 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7741 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7742 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7743 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7744 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7745 module->method_to_callers = g_hash_table_new (NULL, NULL);
7749 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7752 LLVMValueRef res, *vals;
7754 vals = g_new0 (LLVMValueRef, nvalues);
7755 for (i = 0; i < nvalues; ++i)
7756 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7757 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7763 * mono_llvm_emit_aot_file_info:
7765 * Emit the MonoAotFileInfo structure.
7766 * Same as emit_aot_file_info () in aot-compiler.c.
7769 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7771 MonoLLVMModule *module = &aot_module;
7773 /* Save these for later */
7774 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7775 module->has_jitted_code = has_jitted_code;
7779 * mono_llvm_emit_aot_data:
7781 * Emit the binary data DATA pointed to by symbol SYMBOL.
7784 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7786 MonoLLVMModule *module = &aot_module;
7790 type = LLVMArrayType (LLVMInt8Type (), data_len);
7791 d = LLVMAddGlobal (module->lmodule, type, symbol);
7792 LLVMSetVisibility (d, LLVMHiddenVisibility);
7793 LLVMSetLinkage (d, LLVMInternalLinkage);
7794 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7795 mono_llvm_set_is_constant (d);
7798 /* Add a reference to a global defined in JITted code */
7800 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7805 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7806 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7812 emit_aot_file_info (MonoLLVMModule *module)
7814 LLVMTypeRef file_info_type;
7815 LLVMTypeRef *eltypes, eltype;
7816 LLVMValueRef info_var;
7817 LLVMValueRef *fields;
7818 int i, nfields, tindex;
7819 MonoAotFileInfo *info;
7820 LLVMModuleRef lmodule = module->lmodule;
7822 info = &module->aot_info;
7824 /* Create an LLVM type to represent MonoAotFileInfo */
7825 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7826 eltypes = g_new (LLVMTypeRef, nfields);
7828 eltypes [tindex ++] = LLVMInt32Type ();
7829 eltypes [tindex ++] = LLVMInt32Type ();
7831 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7832 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7834 for (i = 0; i < 15; ++i)
7835 eltypes [tindex ++] = LLVMInt32Type ();
7837 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7838 for (i = 0; i < 4; ++i)
7839 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7840 g_assert (tindex == nfields);
7841 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7842 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7844 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7845 if (module->static_link) {
7846 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7847 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7849 fields = g_new (LLVMValueRef, nfields);
7851 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7852 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7856 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7857 * for symbols defined in the .s file emitted by the aot compiler.
7859 eltype = eltypes [tindex];
7860 if (module->llvm_only)
7861 fields [tindex ++] = LLVMConstNull (eltype);
7863 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7864 fields [tindex ++] = module->got_var;
7865 /* llc defines this directly */
7866 if (!module->llvm_only) {
7867 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7868 fields [tindex ++] = LLVMConstNull (eltype);
7869 fields [tindex ++] = LLVMConstNull (eltype);
7871 fields [tindex ++] = LLVMConstNull (eltype);
7872 fields [tindex ++] = module->get_method;
7873 fields [tindex ++] = module->get_unbox_tramp;
7875 if (module->has_jitted_code) {
7876 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7877 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7879 fields [tindex ++] = LLVMConstNull (eltype);
7880 fields [tindex ++] = LLVMConstNull (eltype);
7882 if (!module->llvm_only)
7883 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7885 fields [tindex ++] = LLVMConstNull (eltype);
7886 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7887 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7888 fields [tindex ++] = LLVMConstNull (eltype);
7890 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7891 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7892 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7893 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7894 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7895 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7896 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7897 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7898 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7899 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7901 /* Not needed (mem_end) */
7902 fields [tindex ++] = LLVMConstNull (eltype);
7903 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7904 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7905 if (info->trampoline_size [0]) {
7906 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7907 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7908 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7909 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7911 fields [tindex ++] = LLVMConstNull (eltype);
7912 fields [tindex ++] = LLVMConstNull (eltype);
7913 fields [tindex ++] = LLVMConstNull (eltype);
7914 fields [tindex ++] = LLVMConstNull (eltype);
7916 if (module->static_link && !module->llvm_only)
7917 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7919 fields [tindex ++] = LLVMConstNull (eltype);
7920 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7921 if (!module->llvm_only) {
7922 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7923 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7924 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7925 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7926 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7927 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7929 fields [tindex ++] = LLVMConstNull (eltype);
7930 fields [tindex ++] = LLVMConstNull (eltype);
7931 fields [tindex ++] = LLVMConstNull (eltype);
7932 fields [tindex ++] = LLVMConstNull (eltype);
7933 fields [tindex ++] = LLVMConstNull (eltype);
7934 fields [tindex ++] = LLVMConstNull (eltype);
7937 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7938 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7941 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7942 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7943 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7944 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7945 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7946 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7947 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7948 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7949 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7950 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7951 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7952 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7953 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7954 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7955 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7957 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7958 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7959 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7960 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7961 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7962 g_assert (tindex == nfields);
7964 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7966 if (module->static_link) {
7970 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7971 /* Get rid of characters which cannot occur in symbols */
7973 for (p = s; *p; ++p) {
7974 if (!(isalnum (*p) || *p == '_'))
7977 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7979 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7980 LLVMSetLinkage (var, LLVMExternalLinkage);
7985 * Emit the aot module into the LLVM bitcode file FILENAME.
7988 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7990 LLVMTypeRef got_type, inited_type;
7991 LLVMValueRef real_got, real_inited;
7992 MonoLLVMModule *module = &aot_module;
7994 emit_llvm_code_end (module);
7997 * Create the real got variable and replace all uses of the dummy variable with
8000 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8001 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8002 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8003 if (module->external_symbols) {
8004 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8005 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8007 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8009 mono_llvm_replace_uses_of (module->got_var, real_got);
8011 mark_as_used (&aot_module, real_got);
8013 /* Delete the dummy got so it doesn't become a global */
8014 LLVMDeleteGlobal (module->got_var);
8015 module->got_var = real_got;
8018 * Same for the init_var
8020 if (module->llvm_only) {
8021 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8022 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8023 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8024 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8025 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8026 LLVMDeleteGlobal (module->inited_var);
8029 if (module->llvm_only) {
8030 emit_get_method (&aot_module);
8031 emit_get_unbox_tramp (&aot_module);
8034 emit_llvm_used (&aot_module);
8035 emit_dbg_info (&aot_module, filename, cu_name);
8036 emit_aot_file_info (&aot_module);
8039 * Replace GOT entries for directly callable methods with the methods themselves.
8040 * It would be easier to implement this by predefining all methods before compiling
8041 * their bodies, but that couldn't handle the case when a method fails to compile
8044 if (module->llvm_only) {
8045 GHashTableIter iter;
8047 GSList *callers, *l;
8049 g_hash_table_iter_init (&iter, module->method_to_callers);
8050 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8051 LLVMValueRef lmethod;
8053 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8055 for (l = callers; l; l = l->next) {
8056 LLVMValueRef caller = (LLVMValueRef)l->data;
8058 mono_llvm_replace_uses_of (caller, lmethod);
8064 /* Replace PLT entries for directly callable methods with the methods themselves */
8066 GHashTableIter iter;
8068 LLVMValueRef callee;
8070 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8071 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8072 if (mono_aot_is_direct_callable (ji)) {
8073 LLVMValueRef lmethod;
8075 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8076 /* The types might not match because the caller might pass an rgctx */
8077 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8078 mono_llvm_replace_uses_of (callee, lmethod);
8079 mono_aot_mark_unused_llvm_plt_entry (ji);
8089 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
8090 g_assert_not_reached ();
8095 LLVMWriteBitcodeToFile (module->lmodule, filename);
8100 md_string (const char *s)
8102 return LLVMMDString (s, strlen (s));
8105 /* Debugging support */
8108 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8110 LLVMModuleRef lmodule = module->lmodule;
8111 LLVMValueRef args [16], cu_args [16], cu, ver;
8113 char *build_info, *s, *dir;
8116 * This can only be enabled when LLVM code is emitted into a separate object
8117 * file, since the AOT compiler also emits dwarf info,
8118 * and the abbrev indexes will not be correct since llvm has added its own
8121 if (!module->emit_dwarf)
8125 * Emit dwarf info in the form of LLVM metadata. There is some
8126 * out-of-date documentation at:
8127 * http://llvm.org/docs/SourceLevelDebugging.html
8128 * but most of this was gathered from the llvm and
8133 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8134 /* CU name/compilation dir */
8135 dir = g_path_get_dirname (filename);
8136 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8137 args [1] = LLVMMDString (dir, strlen (dir));
8138 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8141 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8143 build_info = mono_get_runtime_build_info ();
8144 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8145 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8146 g_free (build_info);
8148 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8150 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8151 /* Runtime version */
8152 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8154 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8155 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8157 if (module->subprogram_mds) {
8161 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8162 for (i = 0; i < module->subprogram_mds->len; ++i)
8163 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8164 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8166 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8169 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8170 /* Imported modules */
8171 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8173 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8174 /* DebugEmissionKind = FullDebug */
8175 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8176 cu = LLVMMDNode (cu_args, n_cuargs);
8177 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8179 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8180 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8181 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8182 ver = LLVMMDNode (args, 3);
8183 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8185 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8186 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8187 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8188 ver = LLVMMDNode (args, 3);
8189 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8193 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8195 MonoLLVMModule *module = ctx->module;
8196 MonoDebugMethodInfo *minfo = ctx->minfo;
8197 char *source_file, *dir, *filename;
8198 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8199 MonoSymSeqPoint *sym_seq_points;
8205 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8207 source_file = g_strdup ("<unknown>");
8208 dir = g_path_get_dirname (source_file);
8209 filename = g_path_get_basename (source_file);
8211 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8212 args [0] = md_string (filename);
8213 args [1] = md_string (dir);
8214 ctx_args [1] = LLVMMDNode (args, 2);
8215 ctx_md = LLVMMDNode (ctx_args, 2);
8217 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8218 type_args [1] = NULL;
8219 type_args [2] = NULL;
8220 type_args [3] = LLVMMDString ("", 0);
8221 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8222 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8223 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8224 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8225 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8226 type_args [9] = NULL;
8227 type_args [10] = NULL;
8228 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8229 type_args [12] = NULL;
8230 type_args [13] = NULL;
8231 type_args [14] = NULL;
8232 type_md = LLVMMDNode (type_args, 14);
8234 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8235 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8236 /* Source directory + file pair */
8237 args [0] = md_string (filename);
8238 args [1] = md_string (dir);
8239 md_args [1] = LLVMMDNode (args ,2);
8240 md_args [2] = ctx_md;
8241 md_args [3] = md_string (cfg->method->name);
8242 md_args [4] = md_string (name);
8243 md_args [5] = md_string (name);
8246 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8248 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8250 md_args [7] = type_md;
8252 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8254 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8256 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8257 /* Index into a virtual function */
8258 md_args [11] = NULL;
8259 md_args [12] = NULL;
8261 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8263 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8264 /* Pointer to LLVM function */
8265 md_args [15] = method;
8266 /* Function template parameter */
8267 md_args [16] = NULL;
8268 /* Function declaration descriptor */
8269 md_args [17] = NULL;
8270 /* List of function variables */
8271 md_args [18] = LLVMMDNode (args, 0);
8273 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8274 md = LLVMMDNode (md_args, 20);
8276 if (!module->subprogram_mds)
8277 module->subprogram_mds = g_ptr_array_new ();
8278 g_ptr_array_add (module->subprogram_mds, md);
8282 g_free (source_file);
8283 g_free (sym_seq_points);
8289 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8291 MonoCompile *cfg = ctx->cfg;
8293 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8294 MonoDebugSourceLocation *loc;
8295 LLVMValueRef loc_md, md_args [16];
8298 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8302 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8303 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8304 md_args [nmd_args ++] = ctx->dbg_md;
8305 md_args [nmd_args ++] = NULL;
8306 loc_md = LLVMMDNode (md_args, nmd_args);
8307 LLVMSetCurrentDebugLocation (builder, loc_md);
8308 mono_debug_symfile_free_location (loc);
8314 default_mono_llvm_unhandled_exception (void)
8316 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8317 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8319 mono_unhandled_exception (target);
8320 exit (mono_environment_exitcode_get ());
8325 - Emit LLVM IR from the mono IR using the LLVM C API.
8326 - The original arch specific code remains, so we can fall back to it if we run
8327 into something we can't handle.
8331 A partial list of issues:
8332 - Handling of opcodes which can throw exceptions.
8334 In the mono JIT, these are implemented using code like this:
8341 push throw_pos - method
8342 call <exception trampoline>
8344 The problematic part is push throw_pos - method, which cannot be represented
8345 in the LLVM IR, since it does not support label values.
8346 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8347 be implemented in JIT mode ?
8348 -> a possible but slower implementation would use the normal exception
8349 throwing code but it would need to control the placement of the throw code
8350 (it needs to be exactly after the compare+branch).
8351 -> perhaps add a PC offset intrinsics ?
8353 - efficient implementation of .ovf opcodes.
8355 These are currently implemented as:
8356 <ins which sets the condition codes>
8359 Some overflow opcodes are now supported by LLVM SVN.
8361 - exception handling, unwinding.
8362 - SSA is disabled for methods with exception handlers
8363 - How to obtain unwind info for LLVM compiled methods ?
8364 -> this is now solved by converting the unwind info generated by LLVM
8366 - LLVM uses the c++ exception handling framework, while we use our home grown
8367 code, and couldn't use the c++ one:
8368 - its not supported under VC++, other exotic platforms.
8369 - it might be impossible to support filter clauses with it.
8373 The trampolines need a predictable call sequence, since they need to disasm
8374 the calling code to obtain register numbers / offsets.
8376 LLVM currently generates this code in non-JIT mode:
8377 mov -0x98(%rax),%eax
8379 Here, the vtable pointer is lost.
8380 -> solution: use one vtable trampoline per class.
8382 - passing/receiving the IMT pointer/RGCTX.
8383 -> solution: pass them as normal arguments ?
8387 LLVM does not allow the specification of argument registers etc. This means
8388 that all calls are made according to the platform ABI.
8390 - passing/receiving vtypes.
8392 Vtypes passed/received in registers are handled by the front end by using
8393 a signature with scalar arguments, and loading the parts of the vtype into those
8396 Vtypes passed on the stack are handled using the 'byval' attribute.
8400 Supported though alloca, we need to emit the load/store code.
8404 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8405 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8406 This is made easier because the IR is already in SSA form.
8407 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8408 types are frequently used incorrectly.
8413 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8414 it with the file containing the methods emitted by the JIT and the AOT data
8418 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8419 * - each bblock should end with a branch
8420 * - setting the return value, making cfg->ret non-volatile
8421 * - avoid some transformations in the JIT which make it harder for us to generate
8423 * - use pointer types to help optimizations.