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/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 GHashTable *llvm_types;
51 const char *got_symbol;
52 GHashTable *plt_entries;
53 GHashTable *plt_entries_ji;
54 GHashTable *method_to_lmethod;
59 GPtrArray *subprogram_mds;
61 LLVMExecutionEngineRef ee;
62 gboolean external_symbols;
67 MonoAssembly *assembly;
69 MonoAotFileInfo aot_info;
70 const char *jit_got_symbol;
71 const char *eh_frame_symbol;
72 LLVMValueRef code_start, code_end;
73 gboolean has_jitted_code;
78 * Information associated by the backend with mono basic blocks.
81 LLVMBasicBlockRef bblock, end_bblock;
82 LLVMValueRef finally_ind;
83 gboolean added, invoke_target;
85 * If this bblock is the start of a finally clause, this is a list of bblocks it
86 * needs to branch to in ENDFINALLY.
88 GSList *call_handler_return_bbs;
90 * If this bblock is the start of a finally clause, this is the bblock that
91 * CALL_HANDLER needs to branch to.
93 LLVMBasicBlockRef call_handler_target_bb;
94 /* The list of switch statements generated by ENDFINALLY instructions */
95 GSList *endfinally_switch_ins_list;
100 * Structure containing emit state
103 MonoMemPool *mempool;
105 /* Maps method names to the corresponding LLVMValueRef */
106 GHashTable *emitted_method_decls;
109 LLVMValueRef lmethod;
110 MonoLLVMModule *lmodule;
111 LLVMModuleRef module;
113 int sindex, default_index, ex_index;
114 LLVMBuilderRef builder;
115 LLVMValueRef *values, *addresses;
116 MonoType **vreg_cli_types;
118 MonoMethodSignature *sig;
120 GHashTable *region_to_handler;
121 GHashTable *clause_to_handler;
122 LLVMBuilderRef alloca_builder;
123 LLVMValueRef last_alloca;
124 LLVMValueRef rgctx_arg;
125 LLVMTypeRef *vreg_types;
127 gboolean *unreachable;
129 LLVMValueRef imt_rgctx_loc;
130 GHashTable *llvm_types;
132 MonoDebugMethodInfo *minfo;
134 /* For every clause, the clauses it is nested in */
142 MonoBasicBlock *in_bb;
147 * Instruction metadata
148 * This is the same as ins_info, but LREG != IREG.
156 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
157 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
164 /* keep in sync with the enum in mini.h */
167 #include "mini-ops.h"
172 #if SIZEOF_VOID_P == 4
173 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
175 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
178 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
181 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
183 #define TRACE_FAILURE(msg)
187 #define IS_TARGET_X86 1
189 #define IS_TARGET_X86 0
193 #define IS_TARGET_AMD64 1
195 #define IS_TARGET_AMD64 0
198 #define LLVM_FAILURE(ctx, reason) do { \
199 TRACE_FAILURE (reason); \
200 (ctx)->cfg->exception_message = g_strdup (reason); \
201 (ctx)->cfg->disable_llvm = TRUE; \
205 #define CHECK_FAILURE(ctx) do { \
206 if ((ctx)->cfg->disable_llvm) \
210 static LLVMIntPredicate cond_to_llvm_cond [] = {
223 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
236 static MonoNativeTlsKey current_cfg_tls_id;
238 static MonoLLVMModule aot_module;
239 static int memset_param_count, memcpy_param_count;
240 static const char *memset_func_name;
241 static const char *memcpy_func_name;
243 static void init_jit_module (MonoDomain *domain);
245 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
246 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
247 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
252 * The LLVM type with width == sizeof (gpointer)
257 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
263 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
269 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
275 * Return the size of the LLVM representation of the vtype T.
278 get_vtype_size (MonoType *t)
282 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
284 /* LLVMArgAsIArgs depends on this since it stores whole words */
285 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
292 * simd_class_to_llvm_type:
294 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
297 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
299 if (!strcmp (klass->name, "Vector2d")) {
300 return LLVMVectorType (LLVMDoubleType (), 2);
301 } else if (!strcmp (klass->name, "Vector2l")) {
302 return LLVMVectorType (LLVMInt64Type (), 2);
303 } else if (!strcmp (klass->name, "Vector2ul")) {
304 return LLVMVectorType (LLVMInt64Type (), 2);
305 } else if (!strcmp (klass->name, "Vector4i")) {
306 return LLVMVectorType (LLVMInt32Type (), 4);
307 } else if (!strcmp (klass->name, "Vector4ui")) {
308 return LLVMVectorType (LLVMInt32Type (), 4);
309 } else if (!strcmp (klass->name, "Vector4f")) {
310 return LLVMVectorType (LLVMFloatType (), 4);
311 } else if (!strcmp (klass->name, "Vector8s")) {
312 return LLVMVectorType (LLVMInt16Type (), 8);
313 } else if (!strcmp (klass->name, "Vector8us")) {
314 return LLVMVectorType (LLVMInt16Type (), 8);
315 } else if (!strcmp (klass->name, "Vector16sb")) {
316 return LLVMVectorType (LLVMInt8Type (), 16);
317 } else if (!strcmp (klass->name, "Vector16b")) {
318 return LLVMVectorType (LLVMInt8Type (), 16);
320 printf ("%s\n", klass->name);
326 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
327 static inline G_GNUC_UNUSED LLVMTypeRef
328 type_to_simd_type (int type)
332 return LLVMVectorType (LLVMInt8Type (), 16);
334 return LLVMVectorType (LLVMInt16Type (), 8);
336 return LLVMVectorType (LLVMInt32Type (), 4);
338 return LLVMVectorType (LLVMInt64Type (), 2);
340 return LLVMVectorType (LLVMDoubleType (), 2);
342 return LLVMVectorType (LLVMFloatType (), 4);
344 g_assert_not_reached ();
350 create_llvm_type_for_type (MonoClass *klass)
352 int i, size, nfields, esize;
353 LLVMTypeRef *eltypes;
358 t = &klass->byval_arg;
360 if (mini_type_is_hfa (t, &nfields, &esize)) {
362 * This is needed on arm64 where HFAs are returned in
366 eltypes = g_new (LLVMTypeRef, size);
367 for (i = 0; i < size; ++i)
368 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
370 size = get_vtype_size (t);
372 eltypes = g_new (LLVMTypeRef, size);
373 for (i = 0; i < size; ++i)
374 eltypes [i] = LLVMInt8Type ();
377 name = mono_type_full_name (&klass->byval_arg);
378 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
379 LLVMStructSetBody (ltype, eltypes, size, FALSE);
389 * Return the LLVM type corresponding to T.
392 type_to_llvm_type (EmitContext *ctx, MonoType *t)
395 return LLVMPointerType (LLVMInt8Type (), 0);
397 t = mini_get_underlying_type (t);
400 return LLVMVoidType ();
402 return LLVMInt8Type ();
404 return LLVMInt16Type ();
406 return LLVMInt32Type ();
408 return LLVMInt8Type ();
410 return LLVMInt16Type ();
412 return LLVMInt32Type ();
413 case MONO_TYPE_BOOLEAN:
414 return LLVMInt8Type ();
417 return LLVMInt64Type ();
419 return LLVMInt16Type ();
421 return LLVMFloatType ();
423 return LLVMDoubleType ();
426 return IntPtrType ();
427 case MONO_TYPE_OBJECT:
428 case MONO_TYPE_CLASS:
429 case MONO_TYPE_ARRAY:
430 case MONO_TYPE_SZARRAY:
431 case MONO_TYPE_STRING:
433 return ObjRefType ();
436 /* Because of generic sharing */
437 return ObjRefType ();
438 case MONO_TYPE_GENERICINST:
439 if (!mono_type_generic_inst_is_valuetype (t))
440 return ObjRefType ();
442 case MONO_TYPE_VALUETYPE:
443 case MONO_TYPE_TYPEDBYREF: {
447 klass = mono_class_from_mono_type (t);
449 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
450 return simd_class_to_llvm_type (ctx, klass);
453 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
455 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
457 ltype = create_llvm_type_for_type (klass);
458 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
464 printf ("X: %d\n", t->type);
465 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
466 ctx->cfg->disable_llvm = TRUE;
474 * Return whenever T is an unsigned int type.
477 type_is_unsigned (EmitContext *ctx, MonoType *t)
494 * type_to_llvm_arg_type:
496 * Same as type_to_llvm_type, but treat i8/i16 as i32.
499 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
501 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
504 * This works on all abis except arm64/ios which passes multiple
505 * arguments in one stack slot.
508 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
510 * LLVM generates code which only sets the lower bits, while JITted
511 * code expects all the bits to be set.
513 ptype = LLVMInt32Type ();
521 * llvm_type_to_stack_type:
523 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
526 static G_GNUC_UNUSED LLVMTypeRef
527 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
531 if (type == LLVMInt8Type ())
532 return LLVMInt32Type ();
533 else if (type == LLVMInt16Type ())
534 return LLVMInt32Type ();
535 else if (!cfg->r4fp && type == LLVMFloatType ())
536 return LLVMDoubleType ();
542 * regtype_to_llvm_type:
544 * Return the LLVM type corresponding to the regtype C used in instruction
548 regtype_to_llvm_type (char c)
552 return LLVMInt32Type ();
554 return LLVMInt64Type ();
556 return LLVMDoubleType ();
565 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
568 op_to_llvm_type (int opcode)
573 return LLVMInt8Type ();
576 return LLVMInt8Type ();
579 return LLVMInt16Type ();
582 return LLVMInt16Type ();
585 return LLVMInt32Type ();
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
592 return LLVMFloatType ();
594 return LLVMDoubleType ();
596 return LLVMInt64Type ();
598 return LLVMInt32Type ();
600 return LLVMInt64Type ();
605 return LLVMInt8Type ();
610 return LLVMInt16Type ();
613 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
620 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 printf ("%s\n", mono_inst_name (opcode));
630 g_assert_not_reached ();
636 * load_store_to_llvm_type:
638 * Return the size/sign/zero extension corresponding to the load/store opcode
642 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
648 case OP_LOADI1_MEMBASE:
649 case OP_STOREI1_MEMBASE_REG:
650 case OP_STOREI1_MEMBASE_IMM:
651 case OP_ATOMIC_LOAD_I1:
652 case OP_ATOMIC_STORE_I1:
655 return LLVMInt8Type ();
656 case OP_LOADU1_MEMBASE:
658 case OP_ATOMIC_LOAD_U1:
659 case OP_ATOMIC_STORE_U1:
662 return LLVMInt8Type ();
663 case OP_LOADI2_MEMBASE:
664 case OP_STOREI2_MEMBASE_REG:
665 case OP_STOREI2_MEMBASE_IMM:
666 case OP_ATOMIC_LOAD_I2:
667 case OP_ATOMIC_STORE_I2:
670 return LLVMInt16Type ();
671 case OP_LOADU2_MEMBASE:
673 case OP_ATOMIC_LOAD_U2:
674 case OP_ATOMIC_STORE_U2:
677 return LLVMInt16Type ();
678 case OP_LOADI4_MEMBASE:
679 case OP_LOADU4_MEMBASE:
682 case OP_STOREI4_MEMBASE_REG:
683 case OP_STOREI4_MEMBASE_IMM:
684 case OP_ATOMIC_LOAD_I4:
685 case OP_ATOMIC_STORE_I4:
686 case OP_ATOMIC_LOAD_U4:
687 case OP_ATOMIC_STORE_U4:
689 return LLVMInt32Type ();
690 case OP_LOADI8_MEMBASE:
692 case OP_STOREI8_MEMBASE_REG:
693 case OP_STOREI8_MEMBASE_IMM:
694 case OP_ATOMIC_LOAD_I8:
695 case OP_ATOMIC_STORE_I8:
696 case OP_ATOMIC_LOAD_U8:
697 case OP_ATOMIC_STORE_U8:
699 return LLVMInt64Type ();
700 case OP_LOADR4_MEMBASE:
701 case OP_STORER4_MEMBASE_REG:
702 case OP_ATOMIC_LOAD_R4:
703 case OP_ATOMIC_STORE_R4:
705 return LLVMFloatType ();
706 case OP_LOADR8_MEMBASE:
707 case OP_STORER8_MEMBASE_REG:
708 case OP_ATOMIC_LOAD_R8:
709 case OP_ATOMIC_STORE_R8:
711 return LLVMDoubleType ();
712 case OP_LOAD_MEMBASE:
714 case OP_STORE_MEMBASE_REG:
715 case OP_STORE_MEMBASE_IMM:
716 *size = sizeof (gpointer);
717 return IntPtrType ();
719 g_assert_not_reached ();
727 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
730 ovf_op_to_intrins (int opcode)
734 return "llvm.sadd.with.overflow.i32";
736 return "llvm.uadd.with.overflow.i32";
738 return "llvm.ssub.with.overflow.i32";
740 return "llvm.usub.with.overflow.i32";
742 return "llvm.smul.with.overflow.i32";
744 return "llvm.umul.with.overflow.i32";
746 return "llvm.sadd.with.overflow.i64";
748 return "llvm.uadd.with.overflow.i64";
750 return "llvm.ssub.with.overflow.i64";
752 return "llvm.usub.with.overflow.i64";
754 return "llvm.smul.with.overflow.i64";
756 return "llvm.umul.with.overflow.i64";
758 g_assert_not_reached ();
764 simd_op_to_intrins (int opcode)
767 #if defined(TARGET_X86) || defined(TARGET_AMD64)
769 return "llvm.x86.sse2.min.pd";
771 return "llvm.x86.sse.min.ps";
773 return "llvm.x86.sse41.pminud";
775 return "llvm.x86.sse41.pminuw";
777 return "llvm.x86.sse2.pminu.b";
779 return "llvm.x86.sse2.pmins.w";
781 return "llvm.x86.sse2.max.pd";
783 return "llvm.x86.sse.max.ps";
785 return "llvm.x86.sse3.hadd.pd";
787 return "llvm.x86.sse3.hadd.ps";
789 return "llvm.x86.sse3.hsub.pd";
791 return "llvm.x86.sse3.hsub.ps";
793 return "llvm.x86.sse41.pmaxud";
795 return "llvm.x86.sse41.pmaxuw";
797 return "llvm.x86.sse2.pmaxu.b";
799 return "llvm.x86.sse3.addsub.ps";
801 return "llvm.x86.sse3.addsub.pd";
802 case OP_EXTRACT_MASK:
803 return "llvm.x86.sse2.pmovmskb.128";
806 return "llvm.x86.sse2.psrli.w";
809 return "llvm.x86.sse2.psrli.d";
812 return "llvm.x86.sse2.psrli.q";
815 return "llvm.x86.sse2.pslli.w";
818 return "llvm.x86.sse2.pslli.d";
821 return "llvm.x86.sse2.pslli.q";
824 return "llvm.x86.sse2.psrai.w";
827 return "llvm.x86.sse2.psrai.d";
829 return "llvm.x86.sse2.padds.b";
831 return "llvm.x86.sse2.padds.w";
833 return "llvm.x86.sse2.psubs.b";
835 return "llvm.x86.sse2.psubs.w";
836 case OP_PADDB_SAT_UN:
837 return "llvm.x86.sse2.paddus.b";
838 case OP_PADDW_SAT_UN:
839 return "llvm.x86.sse2.paddus.w";
840 case OP_PSUBB_SAT_UN:
841 return "llvm.x86.sse2.psubus.b";
842 case OP_PSUBW_SAT_UN:
843 return "llvm.x86.sse2.psubus.w";
845 return "llvm.x86.sse2.pavg.b";
847 return "llvm.x86.sse2.pavg.w";
849 return "llvm.x86.sse.sqrt.ps";
851 return "llvm.x86.sse2.sqrt.pd";
853 return "llvm.x86.sse.rsqrt.ps";
855 return "llvm.x86.sse.rcp.ps";
857 return "llvm.x86.sse2.cvtdq2pd";
859 return "llvm.x86.sse2.cvtdq2ps";
861 return "llvm.x86.sse2.cvtpd2dq";
863 return "llvm.x86.sse2.cvtps2dq";
865 return "llvm.x86.sse2.cvtpd2ps";
867 return "llvm.x86.sse2.cvtps2pd";
869 return "llvm.x86.sse2.cvttpd2dq";
871 return "llvm.x86.sse2.cvttps2dq";
873 return "llvm.x86.sse.cmp.ps";
875 return "llvm.x86.sse2.cmp.pd";
877 return "llvm.x86.sse2.packsswb.128";
879 return "llvm.x86.sse2.packssdw.128";
881 return "llvm.x86.sse2.packuswb.128";
883 return "llvm.x86.sse41.packusdw";
885 return "llvm.x86.sse2.pmulh.w";
886 case OP_PMULW_HIGH_UN:
887 return "llvm.x86.sse2.pmulhu.w";
890 g_assert_not_reached ();
896 simd_op_to_llvm_type (int opcode)
898 #if defined(TARGET_X86) || defined(TARGET_AMD64)
902 return type_to_simd_type (MONO_TYPE_R8);
905 return type_to_simd_type (MONO_TYPE_I8);
908 return type_to_simd_type (MONO_TYPE_I4);
913 return type_to_simd_type (MONO_TYPE_I2);
917 return type_to_simd_type (MONO_TYPE_I1);
919 return type_to_simd_type (MONO_TYPE_R4);
922 return type_to_simd_type (MONO_TYPE_I4);
926 return type_to_simd_type (MONO_TYPE_R8);
930 return type_to_simd_type (MONO_TYPE_R4);
931 case OP_EXTRACT_MASK:
932 return type_to_simd_type (MONO_TYPE_I1);
938 return type_to_simd_type (MONO_TYPE_R4);
941 return type_to_simd_type (MONO_TYPE_R8);
943 g_assert_not_reached ();
954 * Return the LLVM basic block corresponding to BB.
956 static LLVMBasicBlockRef
957 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
959 char bb_name_buf [128];
962 if (ctx->bblocks [bb->block_num].bblock == NULL) {
963 if (bb->flags & BB_EXCEPTION_HANDLER) {
964 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
965 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
966 bb_name = bb_name_buf;
967 } else if (bb->block_num < 256) {
968 if (!ctx->lmodule->bb_names) {
969 ctx->lmodule->bb_names_len = 256;
970 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
972 if (!ctx->lmodule->bb_names [bb->block_num]) {
975 n = g_strdup_printf ("BB%d", bb->block_num);
976 mono_memory_barrier ();
977 ctx->lmodule->bb_names [bb->block_num] = n;
979 bb_name = ctx->lmodule->bb_names [bb->block_num];
981 sprintf (bb_name_buf, "BB%d", bb->block_num);
982 bb_name = bb_name_buf;
985 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
986 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
989 return ctx->bblocks [bb->block_num].bblock;
995 * Return the last LLVM bblock corresponding to BB.
996 * This might not be equal to the bb returned by get_bb () since we need to generate
997 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
999 static LLVMBasicBlockRef
1000 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1003 return ctx->bblocks [bb->block_num].end_bblock;
1006 static LLVMBasicBlockRef
1007 gen_bb (EmitContext *ctx, const char *prefix)
1011 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1012 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1018 * Return the target of the patch identified by TYPE and TARGET.
1021 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1025 memset (&ji, 0, sizeof (ji));
1027 ji.data.target = target;
1029 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1035 * Emit code to convert the LLVM value V to DTYPE.
1038 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1040 LLVMTypeRef stype = LLVMTypeOf (v);
1042 if (stype != dtype) {
1043 gboolean ext = FALSE;
1046 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1048 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1050 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1054 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1056 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1057 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1060 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1061 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1062 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1063 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1064 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1065 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1066 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1067 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1069 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1070 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1071 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1072 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1073 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1074 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1076 if (mono_arch_is_soft_float ()) {
1077 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1078 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1079 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1080 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1083 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1084 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1087 LLVMDumpValue (LLVMConstNull (dtype));
1088 g_assert_not_reached ();
1096 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1098 return convert_full (ctx, v, dtype, FALSE);
1102 * emit_volatile_load:
1104 * If vreg is volatile, emit a load from its address.
1107 emit_volatile_load (EmitContext *ctx, int vreg)
1111 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1112 t = ctx->vreg_cli_types [vreg];
1113 if (t && !t->byref) {
1115 * Might have to zero extend since llvm doesn't have
1118 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1119 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1120 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1121 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1122 else if (t->type == MONO_TYPE_U8)
1123 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1130 * emit_volatile_store:
1132 * If VREG is volatile, emit a store from its value to its address.
1135 emit_volatile_store (EmitContext *ctx, int vreg)
1137 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1139 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1140 g_assert (ctx->addresses [vreg]);
1141 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1147 * Maps parameter indexes in the original signature to parameter indexes
1148 * in the LLVM signature.
1151 /* The indexes of various special arguments in the LLVM signature */
1152 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1156 * sig_to_llvm_sig_full:
1158 * Return the LLVM signature corresponding to the mono signature SIG using the
1159 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1162 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1165 LLVMTypeRef ret_type;
1166 LLVMTypeRef *param_types = NULL;
1168 int i, j, pindex, vret_arg_pindex = 0;
1170 gboolean vretaddr = FALSE;
1174 memset (sinfo, 0, sizeof (LLVMSigInfo));
1176 rtype = mini_get_underlying_type (sig->ret);
1177 ret_type = type_to_llvm_type (ctx, rtype);
1178 CHECK_FAILURE (ctx);
1181 switch (cinfo->ret.storage) {
1182 case LLVMArgVtypeInReg:
1183 /* LLVM models this by returning an aggregate value */
1184 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1185 LLVMTypeRef members [2];
1187 members [0] = IntPtrType ();
1188 ret_type = LLVMStructType (members, 1, FALSE);
1190 g_assert_not_reached ();
1193 case LLVMArgVtypeByVal:
1194 /* Vtype returned normally by val */
1196 case LLVMArgVtypeAsScalar:
1197 /* LLVM models this by returning an int */
1198 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1199 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1201 case LLVMArgFpStruct: {
1202 /* Vtype returned as a fp struct */
1203 LLVMTypeRef members [16];
1205 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1206 for (i = 0; i < cinfo->ret.nslots; ++i)
1207 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1208 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1211 case LLVMArgVtypeByRef:
1212 /* Vtype returned using a hidden argument */
1213 ret_type = LLVMVoidType ();
1216 if (mini_type_is_vtype (rtype)) {
1217 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1219 ret_type = LLVMVoidType ();
1225 pindexes = g_new0 (int, sig->param_count);
1226 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1228 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef) {
1230 * Has to be the first argument because of the sret argument attribute
1231 * FIXME: This might conflict with passing 'this' as the first argument, but
1232 * this is only used on arm64 which has a dedicated struct return register.
1235 sinfo->vret_arg_pindex = pindex;
1236 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1237 CHECK_FAILURE (ctx);
1238 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1241 if (cinfo && cinfo->rgctx_arg) {
1243 sinfo->rgctx_arg_pindex = pindex;
1244 param_types [pindex] = ctx->lmodule->ptr_type;
1247 if (cinfo && cinfo->imt_arg) {
1249 sinfo->imt_arg_pindex = pindex;
1250 param_types [pindex] = ctx->lmodule->ptr_type;
1254 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1255 vret_arg_pindex = pindex;
1256 if (cinfo->vret_arg_index == 1) {
1257 /* Add the slots consumed by the first argument */
1258 LLVMArgInfo *ainfo = &cinfo->args [0];
1259 switch (ainfo->storage) {
1260 case LLVMArgVtypeInReg:
1261 for (j = 0; j < 2; ++j) {
1262 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1272 sinfo->vret_arg_pindex = vret_arg_pindex;
1275 if (vretaddr && vret_arg_pindex == pindex)
1276 param_types [pindex ++] = IntPtrType ();
1279 sinfo->this_arg_pindex = pindex;
1280 param_types [pindex ++] = ThisType ();
1282 if (vretaddr && vret_arg_pindex == pindex)
1283 param_types [pindex ++] = IntPtrType ();
1284 for (i = 0; i < sig->param_count; ++i) {
1285 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1287 if (vretaddr && vret_arg_pindex == pindex)
1288 param_types [pindex ++] = IntPtrType ();
1289 pindexes [i] = pindex;
1292 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1296 switch (ainfo->storage) {
1297 case LLVMArgVtypeInReg:
1298 for (j = 0; j < 2; ++j) {
1299 switch (ainfo->pair_storage [j]) {
1301 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1306 g_assert_not_reached ();
1310 case LLVMArgVtypeByVal:
1311 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1312 CHECK_FAILURE (ctx);
1313 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1316 case LLVMArgAsIArgs:
1317 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1320 case LLVMArgVtypeByRef:
1321 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1322 CHECK_FAILURE (ctx);
1323 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1326 case LLVMArgAsFpArgs: {
1329 for (j = 0; j < ainfo->nslots; ++j)
1330 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1331 pindex += ainfo->nslots;
1334 case LLVMArgVtypeAsScalar:
1335 g_assert_not_reached ();
1338 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1342 if (vretaddr && vret_arg_pindex == pindex)
1343 param_types [pindex ++] = IntPtrType ();
1345 CHECK_FAILURE (ctx);
1347 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1348 g_free (param_types);
1351 sinfo->pindexes = pindexes;
1359 g_free (param_types);
1365 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1367 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1371 * LLVMFunctionType1:
1373 * Create an LLVM function type from the arguments.
1375 static G_GNUC_UNUSED LLVMTypeRef
1376 LLVMFunctionType1(LLVMTypeRef ReturnType,
1377 LLVMTypeRef ParamType1,
1380 LLVMTypeRef param_types [1];
1382 param_types [0] = ParamType1;
1384 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1388 * LLVMFunctionType2:
1390 * Create an LLVM function type from the arguments.
1392 static G_GNUC_UNUSED LLVMTypeRef
1393 LLVMFunctionType2(LLVMTypeRef ReturnType,
1394 LLVMTypeRef ParamType1,
1395 LLVMTypeRef ParamType2,
1398 LLVMTypeRef param_types [2];
1400 param_types [0] = ParamType1;
1401 param_types [1] = ParamType2;
1403 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1407 * LLVMFunctionType3:
1409 * Create an LLVM function type from the arguments.
1411 static G_GNUC_UNUSED LLVMTypeRef
1412 LLVMFunctionType3(LLVMTypeRef ReturnType,
1413 LLVMTypeRef ParamType1,
1414 LLVMTypeRef ParamType2,
1415 LLVMTypeRef ParamType3,
1418 LLVMTypeRef param_types [3];
1420 param_types [0] = ParamType1;
1421 param_types [1] = ParamType2;
1422 param_types [2] = ParamType3;
1424 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1430 * Create an LLVM builder and remember it so it can be freed later.
1432 static LLVMBuilderRef
1433 create_builder (EmitContext *ctx)
1435 LLVMBuilderRef builder = LLVMCreateBuilder ();
1437 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1443 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1445 char *callee_name = mono_aot_get_plt_symbol (type, data);
1446 LLVMValueRef callee;
1447 MonoJumpInfo *ji = NULL;
1452 if (ctx->cfg->compile_aot)
1453 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1454 mono_add_patch_info (ctx->cfg, 0, type, data);
1457 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1459 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1461 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1463 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1466 if (ctx->cfg->compile_aot) {
1467 ji = g_new0 (MonoJumpInfo, 1);
1469 ji->data.target = data;
1471 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1478 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1480 MonoMethodHeader *header = cfg->header;
1481 MonoExceptionClause *clause;
1485 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1486 return (bb->region >> 8) - 1;
1489 for (i = 0; i < header->num_clauses; ++i) {
1490 clause = &header->clauses [i];
1492 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1500 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1502 LLVMValueRef md_arg;
1505 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1506 md_arg = LLVMMDString ("mono", 4);
1507 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1511 set_invariant_load_flag (LLVMValueRef v)
1513 LLVMValueRef md_arg;
1515 const char *flag_name;
1517 // FIXME: Cache this
1518 flag_name = "invariant.load";
1519 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1520 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1521 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1527 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1531 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1533 MonoCompile *cfg = ctx->cfg;
1535 LLVMBuilderRef builder = *builder_ref;
1538 clause_index = get_handler_clause (cfg, bb);
1540 if (clause_index != -1) {
1541 MonoMethodHeader *header = cfg->header;
1542 MonoExceptionClause *ec = &header->clauses [clause_index];
1543 MonoBasicBlock *tblock;
1544 LLVMBasicBlockRef ex_bb, noex_bb;
1547 * Have to use an invoke instead of a call, branching to the
1548 * handler bblock of the clause containing this bblock.
1551 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1553 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1556 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1558 ex_bb = get_bb (ctx, tblock);
1560 noex_bb = gen_bb (ctx, "NOEX_BB");
1563 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1565 builder = ctx->builder = create_builder (ctx);
1566 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1568 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1570 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1571 ctx->builder = builder;
1574 *builder_ref = ctx->builder;
1580 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1582 const char *intrins_name;
1583 LLVMValueRef args [16], res;
1584 LLVMTypeRef addr_type;
1586 if (is_faulting && bb->region != -1) {
1587 LLVMAtomicOrdering ordering;
1590 case LLVM_BARRIER_NONE:
1591 ordering = LLVMAtomicOrderingNotAtomic;
1593 case LLVM_BARRIER_ACQ:
1594 ordering = LLVMAtomicOrderingAcquire;
1596 case LLVM_BARRIER_SEQ:
1597 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1600 g_assert_not_reached ();
1605 * We handle loads which can fault by calling a mono specific intrinsic
1606 * using an invoke, so they are handled properly inside try blocks.
1607 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1608 * are marked with IntrReadArgMem.
1612 intrins_name = "llvm.mono.load.i8.p0i8";
1615 intrins_name = "llvm.mono.load.i16.p0i16";
1618 intrins_name = "llvm.mono.load.i32.p0i32";
1621 intrins_name = "llvm.mono.load.i64.p0i64";
1624 g_assert_not_reached ();
1627 addr_type = LLVMTypeOf (addr);
1628 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1629 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1632 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1633 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1634 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1635 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1637 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1638 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1639 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1640 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1647 * We emit volatile loads for loads which can fault, because otherwise
1648 * LLVM will generate invalid code when encountering a load from a
1651 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1653 /* Mark it with a custom metadata */
1656 set_metadata_flag (res, "mono.faulting.load");
1664 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1666 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1670 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1672 const char *intrins_name;
1673 LLVMValueRef args [16];
1675 if (is_faulting && bb->region != -1) {
1676 LLVMAtomicOrdering ordering;
1679 case LLVM_BARRIER_NONE:
1680 ordering = LLVMAtomicOrderingNotAtomic;
1682 case LLVM_BARRIER_REL:
1683 ordering = LLVMAtomicOrderingRelease;
1685 case LLVM_BARRIER_SEQ:
1686 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1689 g_assert_not_reached ();
1695 intrins_name = "llvm.mono.store.i8.p0i8";
1698 intrins_name = "llvm.mono.store.i16.p0i16";
1701 intrins_name = "llvm.mono.store.i32.p0i32";
1704 intrins_name = "llvm.mono.store.i64.p0i64";
1707 g_assert_not_reached ();
1710 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1711 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1712 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1717 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1718 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1719 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1720 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1722 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1727 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1729 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1733 * emit_cond_system_exception:
1735 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1736 * Might set the ctx exception.
1739 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1741 LLVMBasicBlockRef ex_bb, noex_bb;
1742 LLVMBuilderRef builder;
1743 MonoClass *exc_class;
1744 LLVMValueRef args [2];
1746 ex_bb = gen_bb (ctx, "EX_BB");
1747 noex_bb = gen_bb (ctx, "NOEX_BB");
1749 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1751 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1752 g_assert (exc_class);
1754 /* Emit exception throwing code */
1755 builder = create_builder (ctx);
1756 LLVMPositionBuilderAtEnd (builder, ex_bb);
1758 if (!ctx->lmodule->throw_corlib_exception) {
1759 LLVMValueRef callee;
1761 const char *icall_name;
1763 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1764 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1765 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1766 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1767 /* This will become i8* */
1768 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1769 sig = sig_to_llvm_sig (ctx, throw_sig);
1771 if (ctx->cfg->compile_aot) {
1772 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1774 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1777 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1778 * - On x86, LLVM generated code doesn't push the arguments
1779 * - The trampoline takes the throw address as an arguments, not a pc offset.
1781 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1784 mono_memory_barrier ();
1785 ctx->lmodule->throw_corlib_exception = callee;
1788 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1789 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1791 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1794 * The LLVM mono branch contains changes so a block address can be passed as an
1795 * argument to a call.
1797 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1798 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1800 LLVMBuildUnreachable (builder);
1802 ctx->builder = create_builder (ctx);
1803 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1805 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1812 * emit_args_to_vtype:
1814 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1817 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1819 int j, size, nslots;
1821 size = get_vtype_size (t);
1823 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1824 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1827 if (ainfo->storage == LLVMArgAsFpArgs)
1828 nslots = ainfo->nslots;
1832 for (j = 0; j < nslots; ++j) {
1833 LLVMValueRef index [2], addr, daddr;
1834 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1835 LLVMTypeRef part_type;
1837 if (ainfo->pair_storage [j] == LLVMArgNone)
1840 switch (ainfo->pair_storage [j]) {
1841 case LLVMArgInIReg: {
1842 part_type = LLVMIntType (part_size * 8);
1843 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1844 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1845 addr = LLVMBuildGEP (builder, address, index, 1, "");
1847 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1848 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1849 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1851 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1854 case LLVMArgInFPReg: {
1855 LLVMTypeRef arg_type;
1857 if (ainfo->esize == 8)
1858 arg_type = LLVMDoubleType ();
1860 arg_type = LLVMFloatType ();
1862 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1863 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1864 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1865 LLVMBuildStore (builder, args [j], addr);
1871 g_assert_not_reached ();
1874 size -= sizeof (gpointer);
1879 * emit_vtype_to_args:
1881 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1882 * into ARGS, and the number of arguments into NARGS.
1885 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1888 int j, size, nslots;
1889 LLVMTypeRef arg_type;
1891 size = get_vtype_size (t);
1893 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1894 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1896 if (ainfo->storage == LLVMArgAsFpArgs)
1897 nslots = ainfo->nslots;
1900 for (j = 0; j < nslots; ++j) {
1901 LLVMValueRef index [2], addr, daddr;
1902 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1904 if (ainfo->pair_storage [j] == LLVMArgNone)
1907 switch (ainfo->pair_storage [j]) {
1909 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1910 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1911 addr = LLVMBuildGEP (builder, address, index, 1, "");
1913 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1914 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1915 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1917 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1919 case LLVMArgInFPReg:
1920 if (ainfo->esize == 8)
1921 arg_type = LLVMDoubleType ();
1923 arg_type = LLVMFloatType ();
1924 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1925 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1926 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1927 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1932 g_assert_not_reached ();
1934 size -= sizeof (gpointer);
1941 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1944 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1945 * get executed every time control reaches them.
1947 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1949 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1950 return ctx->last_alloca;
1954 build_alloca (EmitContext *ctx, MonoType *t)
1956 MonoClass *k = mono_class_from_mono_type (t);
1959 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1962 align = mono_class_min_align (k);
1964 /* Sometimes align is not a power of 2 */
1965 while (mono_is_power_of_two (align) == -1)
1968 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1972 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1975 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1978 lmodule->used = g_ptr_array_sized_new (16);
1979 g_ptr_array_add (lmodule->used, global);
1983 emit_llvm_used (MonoLLVMModule *lmodule)
1985 LLVMModuleRef module = lmodule->module;
1986 LLVMTypeRef used_type;
1987 LLVMValueRef used, *used_elem;
1993 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1994 used = LLVMAddGlobal (module, used_type, "llvm.used");
1995 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1996 for (i = 0; i < lmodule->used->len; ++i)
1997 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1998 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1999 LLVMSetLinkage (used, LLVMAppendingLinkage);
2000 LLVMSetSection (used, "llvm.metadata");
2004 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2006 gboolean need_div_check = FALSE;
2008 #ifdef MONO_ARCH_NEED_DIV_CHECK
2009 need_div_check = TRUE;
2012 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2013 need_div_check = TRUE;
2015 if (!need_div_check)
2018 switch (ins->opcode) {
2031 case OP_IDIV_UN_IMM:
2032 case OP_LDIV_UN_IMM:
2033 case OP_IREM_UN_IMM:
2034 case OP_LREM_UN_IMM: {
2036 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2037 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2039 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2040 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2041 CHECK_FAILURE (ctx);
2042 builder = ctx->builder;
2044 /* b == -1 && a == 0x80000000 */
2046 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2047 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2048 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2050 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2051 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2052 CHECK_FAILURE (ctx);
2053 builder = ctx->builder;
2068 * Emit code to load/convert arguments.
2071 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2074 MonoCompile *cfg = ctx->cfg;
2075 MonoMethodSignature *sig = ctx->sig;
2076 LLVMCallInfo *linfo = ctx->linfo;
2079 ctx->alloca_builder = create_builder (ctx);
2082 * Handle indirect/volatile variables by allocating memory for them
2083 * using 'alloca', and storing their address in a temporary.
2085 for (i = 0; i < cfg->num_varinfo; ++i) {
2086 MonoInst *var = cfg->varinfo [i];
2089 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (var->inst_vtype)) {
2090 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2091 CHECK_FAILURE (ctx);
2092 /* Could be already created by an OP_VPHI */
2093 if (!ctx->addresses [var->dreg])
2094 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2095 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2099 for (i = 0; i < sig->param_count; ++i) {
2100 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2101 int reg = cfg->args [i + sig->hasthis]->dreg;
2103 switch (ainfo->storage) {
2104 case LLVMArgVtypeInReg:
2105 case LLVMArgAsFpArgs: {
2106 LLVMValueRef args [8];
2109 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2110 memset (args, 0, sizeof (args));
2111 pindex = ctx->pindexes [i];
2112 if (ainfo->storage == LLVMArgVtypeInReg) {
2113 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2114 if (ainfo->pair_storage [1] != LLVMArgNone)
2115 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2117 g_assert (ainfo->nslots <= 8);
2118 for (j = 0; j < ainfo->nslots; ++j)
2119 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2121 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2123 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2125 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2126 /* Treat these as normal values */
2127 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2131 case LLVMArgVtypeByVal: {
2132 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2134 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2135 /* Treat these as normal values */
2136 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2140 case LLVMArgVtypeByRef: {
2141 /* The argument is passed by ref */
2142 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2145 case LLVMArgAsIArgs: {
2146 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2148 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2150 /* The argument is received as an array of ints, store it into the real argument */
2151 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2154 case LLVMArgVtypeAsScalar:
2155 g_assert_not_reached ();
2158 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->params [i])), type_is_unsigned (ctx, sig->params [i]));
2164 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2166 emit_volatile_store (ctx, cfg->args [0]->dreg);
2167 for (i = 0; i < sig->param_count; ++i)
2168 if (!mini_type_is_vtype (sig->params [i]))
2169 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2171 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2172 LLVMValueRef this_alloc;
2175 * The exception handling code needs the location where the this argument was
2176 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2177 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2178 * location into the LSDA.
2180 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2181 /* This volatile store will keep the alloca alive */
2182 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2184 set_metadata_flag (this_alloc, "mono.this");
2187 if (cfg->rgctx_var) {
2188 LLVMValueRef rgctx_alloc, store;
2191 * We handle the rgctx arg similarly to the this pointer.
2193 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2194 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2195 /* This volatile store will keep the alloca alive */
2196 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2198 set_metadata_flag (rgctx_alloc, "mono.this");
2201 /* Compute nesting between clauses */
2202 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2203 for (i = 0; i < cfg->header->num_clauses; ++i) {
2204 for (j = 0; j < cfg->header->num_clauses; ++j) {
2205 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2206 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2208 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2209 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2214 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2215 * it needs to continue normally, or return back to the exception handling system.
2217 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2221 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2224 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2225 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2226 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2228 if (bb->in_scount == 0) {
2231 sprintf (name, "finally_ind_bb%d", bb->block_num);
2232 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2233 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2235 ctx->bblocks [bb->block_num].finally_ind = val;
2237 /* Create a variable to hold the exception var */
2239 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2243 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2244 * LLVM bblock containing a landing pad causes problems for the
2245 * LLVM optimizer passes.
2247 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2248 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2255 /* Have to export this for AOT */
2257 mono_personality (void)
2260 g_assert_not_reached ();
2264 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2266 MonoCompile *cfg = ctx->cfg;
2267 LLVMModuleRef module = ctx->module;
2268 LLVMValueRef *values = ctx->values;
2269 LLVMValueRef *addresses = ctx->addresses;
2270 MonoCallInst *call = (MonoCallInst*)ins;
2271 MonoMethodSignature *sig = call->signature;
2272 LLVMValueRef callee = NULL, lcall;
2274 LLVMCallInfo *cinfo;
2278 LLVMTypeRef llvm_sig;
2280 gboolean virtual, calli;
2281 LLVMBuilderRef builder = *builder_ref;
2284 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2285 LLVM_FAILURE (ctx, "non-default callconv");
2287 cinfo = call->cinfo;
2288 if (call->rgctx_arg_reg)
2289 cinfo->rgctx_arg = TRUE;
2290 if (call->imt_arg_reg)
2291 cinfo->imt_arg = TRUE;
2293 vretaddr = cinfo && (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef);
2295 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2296 CHECK_FAILURE (ctx);
2298 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);
2299 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);
2301 /* FIXME: Avoid creating duplicate methods */
2303 if (ins->flags & MONO_INST_HAS_METHOD) {
2307 if (cfg->compile_aot) {
2308 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2310 LLVM_FAILURE (ctx, "can't encode patch");
2312 callee = LLVMAddFunction (module, "", llvm_sig);
2315 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2317 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2321 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2322 /* LLVM miscompiles async methods */
2323 LLVM_FAILURE (ctx, "#13734");
2326 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2332 memset (&ji, 0, sizeof (ji));
2333 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2334 ji.data.target = info->name;
2336 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2338 if (cfg->compile_aot) {
2339 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2341 LLVM_FAILURE (ctx, "can't encode patch");
2343 callee = LLVMAddFunction (module, "", llvm_sig);
2344 target = (gpointer)mono_icall_get_wrapper (info);
2345 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2348 if (cfg->compile_aot) {
2350 if (cfg->abs_patches) {
2351 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2353 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2355 LLVM_FAILURE (ctx, "can't encode patch");
2359 LLVM_FAILURE (ctx, "aot");
2361 callee = LLVMAddFunction (module, "", llvm_sig);
2363 if (cfg->abs_patches) {
2364 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2367 * FIXME: Some trampolines might have
2368 * their own calling convention on some platforms.
2370 #ifndef TARGET_AMD64
2371 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2372 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2373 LLVM_FAILURE (ctx, "trampoline with own cconv");
2375 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2376 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2380 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2386 int size = sizeof (gpointer);
2389 g_assert (ins->inst_offset % size == 0);
2390 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2392 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2394 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2396 if (ins->flags & MONO_INST_HAS_METHOD) {
2401 * Collect and convert arguments
2403 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2404 len = sizeof (LLVMValueRef) * nargs;
2405 args = alloca (len);
2406 memset (args, 0, len);
2407 l = call->out_ireg_args;
2409 if (call->rgctx_arg_reg) {
2410 g_assert (values [call->rgctx_arg_reg]);
2411 g_assert (sinfo.rgctx_arg_pindex < nargs);
2413 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2414 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2415 * it using a volatile load.
2418 if (!ctx->imt_rgctx_loc)
2419 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2420 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2421 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2423 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2426 if (call->imt_arg_reg) {
2427 g_assert (values [call->imt_arg_reg]);
2428 g_assert (sinfo.imt_arg_pindex < nargs);
2430 if (!ctx->imt_rgctx_loc)
2431 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2432 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2433 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2435 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2439 if (!addresses [call->inst.dreg])
2440 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2441 g_assert (sinfo.vret_arg_pindex < nargs);
2442 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
2443 args [sinfo.vret_arg_pindex] = addresses [call->inst.dreg];
2445 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2448 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2451 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2455 pindex = sinfo.this_arg_pindex;
2457 pindex = sinfo.pindexes [i - 1];
2459 pindex = sinfo.pindexes [i];
2462 regpair = (guint32)(gssize)(l->data);
2463 reg = regpair & 0xffffff;
2464 args [pindex] = values [reg];
2465 switch (ainfo->storage) {
2466 case LLVMArgVtypeInReg:
2467 case LLVMArgAsFpArgs: {
2470 g_assert (addresses [reg]);
2471 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2475 // FIXME: Get rid of the VMOVE
2478 case LLVMArgVtypeByVal:
2479 g_assert (addresses [reg]);
2480 args [pindex] = addresses [reg];
2482 case LLVMArgVtypeByRef:
2483 g_assert (addresses [reg]);
2484 args [pindex] = addresses [reg];
2486 case LLVMArgAsIArgs:
2487 g_assert (addresses [reg]);
2488 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2490 case LLVMArgVtypeAsScalar:
2491 g_assert_not_reached ();
2494 g_assert (args [pindex]);
2495 if (i == 0 && sig->hasthis)
2496 args [pindex] = convert (ctx, args [pindex], ThisType ());
2498 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2501 g_assert (pindex <= nargs);
2506 // FIXME: Align call sites
2512 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2515 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2517 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2518 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2520 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2521 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2523 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2525 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
2526 LLVMAddInstrAttribute (lcall, 1 + sinfo.vret_arg_pindex, LLVMStructRetAttribute);
2527 if (call->rgctx_arg_reg)
2528 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2529 if (call->imt_arg_reg)
2530 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2532 /* Add byval attributes if needed */
2533 for (i = 0; i < sig->param_count; ++i) {
2534 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2536 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2537 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2542 * Convert the result
2545 switch (cinfo->ret.storage) {
2546 case LLVMArgVtypeInReg: {
2547 LLVMValueRef regs [2];
2549 if (!addresses [ins->dreg])
2550 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2552 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2553 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2554 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2555 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2558 case LLVMArgVtypeByVal:
2559 if (!addresses [call->inst.dreg])
2560 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2561 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2563 case LLVMArgFpStruct:
2564 if (!addresses [call->inst.dreg])
2565 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2566 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2568 case LLVMArgVtypeAsScalar:
2569 if (!addresses [call->inst.dreg])
2570 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2571 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2574 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2575 /* If the method returns an unsigned value, need to zext it */
2576 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));
2580 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2581 /* If the method returns an unsigned value, need to zext it */
2582 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));
2586 if (!addresses [call->inst.dreg])
2587 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2588 g_assert (sinfo.vret_arg_pindex < nargs);
2589 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2592 *builder_ref = ctx->builder;
2594 g_free (sinfo.pindexes);
2602 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2604 MonoCompile *cfg = ctx->cfg;
2605 LLVMValueRef *values = ctx->values;
2606 LLVMModuleRef module = ctx->module;
2607 BBInfo *bblocks = ctx->bblocks;
2609 LLVMValueRef personality;
2610 LLVMValueRef landing_pad;
2611 LLVMBasicBlockRef target_bb;
2613 static gint32 mapping_inited;
2614 static int ti_generator;
2617 LLVMValueRef type_info;
2621 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2623 if (cfg->compile_aot) {
2624 /* Use a dummy personality function */
2625 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2626 g_assert (personality);
2628 personality = LLVMGetNamedFunction (module, "mono_personality");
2629 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2630 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2633 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2635 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2638 * Create the type info
2640 sprintf (ti_name, "type_info_%d", ti_generator);
2643 if (cfg->compile_aot) {
2644 /* decode_eh_frame () in aot-runtime.c will decode this */
2645 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2646 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2649 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2651 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2654 * After the cfg mempool is freed, the type info will point to stale memory,
2655 * but this is not a problem, since we decode it once in exception_cb during
2658 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2659 *(gint32*)ti = clause_index;
2661 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2663 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2667 LLVMTypeRef members [2], ret_type;
2669 members [0] = i8ptr;
2670 members [1] = LLVMInt32Type ();
2671 ret_type = LLVMStructType (members, 2, FALSE);
2673 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2674 LLVMAddClause (landing_pad, type_info);
2676 /* Store the exception into the exvar */
2678 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2682 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2683 * code expects control to be transferred to this landing pad even in the
2684 * presence of nested clauses. The landing pad needs to branch to the landing
2685 * pads belonging to nested clauses based on the selector value returned by
2686 * the landing pad instruction, which is passed to the landing pad in a
2687 * register by the EH code.
2689 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2690 g_assert (target_bb);
2693 * Branch to the correct landing pad
2695 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2696 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2698 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2699 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2700 MonoBasicBlock *handler_bb;
2702 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2703 g_assert (handler_bb);
2705 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2706 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2709 /* Start a new bblock which CALL_HANDLER can branch to */
2710 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2712 ctx->builder = builder = create_builder (ctx);
2713 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2715 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2717 /* Store the exception into the IL level exvar */
2718 if (bb->in_scount == 1) {
2719 g_assert (bb->in_scount == 1);
2720 exvar = bb->in_stack [0];
2722 // FIXME: This is shared with filter clauses ?
2723 g_assert (!values [exvar->dreg]);
2725 g_assert (ctx->ex_var);
2726 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2727 emit_volatile_store (ctx, exvar->dreg);
2733 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2735 MonoCompile *cfg = ctx->cfg;
2736 MonoMethodSignature *sig = ctx->sig;
2737 LLVMValueRef method = ctx->lmethod;
2738 LLVMValueRef *values = ctx->values;
2739 LLVMValueRef *addresses = ctx->addresses;
2740 LLVMCallInfo *linfo = ctx->linfo;
2741 LLVMModuleRef module = ctx->module;
2742 BBInfo *bblocks = ctx->bblocks;
2744 LLVMBasicBlockRef cbb;
2745 LLVMBuilderRef builder, starting_builder;
2746 gboolean has_terminator;
2748 LLVMValueRef lhs, rhs;
2751 cbb = get_bb (ctx, bb);
2752 builder = create_builder (ctx);
2753 ctx->builder = builder;
2754 LLVMPositionBuilderAtEnd (builder, cbb);
2756 if (bb == cfg->bb_entry)
2757 emit_entry_bb (ctx, builder);
2758 CHECK_FAILURE (ctx);
2760 if (bb->flags & BB_EXCEPTION_HANDLER) {
2761 if (!bblocks [bb->block_num].invoke_target) {
2762 //LLVM_FAILURE (ctx, "handler without invokes");
2765 emit_handler_start (ctx, bb, builder);
2766 CHECK_FAILURE (ctx);
2767 builder = ctx->builder;
2770 has_terminator = FALSE;
2771 starting_builder = builder;
2772 for (ins = bb->code; ins; ins = ins->next) {
2773 const char *spec = LLVM_INS_INFO (ins->opcode);
2775 char dname_buf [128];
2777 emit_dbg_loc (ctx, builder, ins->cil_code);
2780 if (nins > 3000 && builder == starting_builder) {
2781 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2782 LLVM_FAILURE (ctx, "basic block too long");
2786 /* There could be instructions after a terminator, skip them */
2789 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2790 sprintf (dname_buf, "t%d", ins->dreg);
2794 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2795 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2797 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2798 lhs = emit_volatile_load (ctx, ins->sreg1);
2800 /* It is ok for SETRET to have an uninitialized argument */
2801 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2802 LLVM_FAILURE (ctx, "sreg1");
2803 lhs = values [ins->sreg1];
2809 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2810 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2811 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2812 rhs = emit_volatile_load (ctx, ins->sreg2);
2814 if (!values [ins->sreg2])
2815 LLVM_FAILURE (ctx, "sreg2");
2816 rhs = values [ins->sreg2];
2822 //mono_print_ins (ins);
2823 switch (ins->opcode) {
2826 case OP_LIVERANGE_START:
2827 case OP_LIVERANGE_END:
2830 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2833 #if SIZEOF_VOID_P == 4
2834 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2836 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2840 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2844 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2846 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2848 case OP_DUMMY_ICONST:
2849 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2851 case OP_DUMMY_I8CONST:
2852 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2854 case OP_DUMMY_R8CONST:
2855 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2858 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2859 has_terminator = TRUE;
2865 LLVMBasicBlockRef new_bb;
2866 LLVMBuilderRef new_builder;
2868 // The default branch is already handled
2869 // FIXME: Handle it here
2871 /* Start new bblock */
2872 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2873 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2875 lhs = convert (ctx, lhs, LLVMInt32Type ());
2876 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2877 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2878 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2880 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2883 new_builder = create_builder (ctx);
2884 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2885 LLVMBuildUnreachable (new_builder);
2887 has_terminator = TRUE;
2888 g_assert (!ins->next);
2894 switch (linfo->ret.storage) {
2895 case LLVMArgVtypeInReg: {
2896 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2897 LLVMValueRef part1, retval;
2900 size = get_vtype_size (sig->ret);
2902 g_assert (addresses [ins->sreg1]);
2904 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2905 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2907 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2909 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2911 LLVMBuildRet (builder, retval);
2914 case LLVMArgVtypeAsScalar: {
2915 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2916 LLVMValueRef retval;
2919 size = get_vtype_size (sig->ret);
2921 g_assert (addresses [ins->sreg1]);
2923 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
2924 LLVMBuildRet (builder, retval);
2927 case LLVMArgVtypeByVal: {
2928 LLVMValueRef retval;
2930 g_assert (addresses [ins->sreg1]);
2931 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2932 LLVMBuildRet (builder, retval);
2935 case LLVMArgVtypeByRef: {
2936 LLVMBuildRetVoid (builder);
2939 case LLVMArgVtypeRetAddr: {
2940 LLVMBuildRetVoid (builder);
2943 case LLVMArgFpStruct: {
2944 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2945 LLVMValueRef retval;
2947 g_assert (addresses [ins->sreg1]);
2948 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2949 LLVMBuildRet (builder, retval);
2953 if (!lhs || ctx->is_dead [ins->sreg1]) {
2955 * The method did not set its return value, probably because it
2956 * ends with a throw.
2959 LLVMBuildRetVoid (builder);
2961 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2963 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2965 has_terminator = TRUE;
2975 case OP_ICOMPARE_IMM:
2976 case OP_LCOMPARE_IMM:
2977 case OP_COMPARE_IMM: {
2981 if (ins->next->opcode == OP_NOP)
2984 if (ins->next->opcode == OP_BR)
2985 /* The comparison result is not needed */
2988 rel = mono_opcode_to_cond (ins->next->opcode);
2990 if (ins->opcode == OP_ICOMPARE_IMM) {
2991 lhs = convert (ctx, lhs, LLVMInt32Type ());
2992 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2994 if (ins->opcode == OP_LCOMPARE_IMM) {
2995 lhs = convert (ctx, lhs, LLVMInt64Type ());
2996 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2998 if (ins->opcode == OP_LCOMPARE) {
2999 lhs = convert (ctx, lhs, LLVMInt64Type ());
3000 rhs = convert (ctx, rhs, LLVMInt64Type ());
3002 if (ins->opcode == OP_ICOMPARE) {
3003 lhs = convert (ctx, lhs, LLVMInt32Type ());
3004 rhs = convert (ctx, rhs, LLVMInt32Type ());
3008 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3009 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
3010 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
3011 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
3014 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
3015 if (ins->opcode == OP_FCOMPARE) {
3016 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3017 } else if (ins->opcode == OP_RCOMPARE) {
3018 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3019 } else if (ins->opcode == OP_COMPARE_IMM) {
3020 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
3021 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
3023 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
3024 } else if (ins->opcode == OP_LCOMPARE_IMM) {
3025 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
3026 /* The immediate is encoded in two fields */
3027 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
3028 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
3030 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
3033 else if (ins->opcode == OP_COMPARE) {
3034 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
3035 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3037 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
3039 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3041 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
3042 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
3044 * If the target bb contains PHI instructions, LLVM requires
3045 * two PHI entries for this bblock, while we only generate one.
3046 * So convert this to an unconditional bblock. (bxc #171).
3048 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
3050 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
3052 has_terminator = TRUE;
3053 } else if (MONO_IS_SETCC (ins->next)) {
3054 sprintf (dname_buf, "t%d", ins->next->dreg);
3056 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3058 /* Add stores for volatile variables */
3059 emit_volatile_store (ctx, ins->next->dreg);
3060 } else if (MONO_IS_COND_EXC (ins->next)) {
3061 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
3062 CHECK_FAILURE (ctx);
3063 builder = ctx->builder;
3065 LLVM_FAILURE (ctx, "next");
3079 rel = mono_opcode_to_cond (ins->opcode);
3081 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3082 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3093 rel = mono_opcode_to_cond (ins->opcode);
3095 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3096 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3104 gboolean empty = TRUE;
3106 /* Check that all input bblocks really branch to us */
3107 for (i = 0; i < bb->in_count; ++i) {
3108 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3109 ins->inst_phi_args [i + 1] = -1;
3115 /* LLVM doesn't like phi instructions with zero operands */
3116 ctx->is_dead [ins->dreg] = TRUE;
3120 /* Created earlier, insert it now */
3121 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3123 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3124 int sreg1 = ins->inst_phi_args [i + 1];
3128 * Count the number of times the incoming bblock branches to us,
3129 * since llvm requires a separate entry for each.
3131 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3132 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3135 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3136 if (switch_ins->inst_many_bb [j] == bb)
3143 /* Remember for later */
3144 for (j = 0; j < count; ++j) {
3145 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3148 node->in_bb = bb->in_bb [i];
3150 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);
3160 values [ins->dreg] = lhs;
3164 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3167 values [ins->dreg] = lhs;
3169 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3171 * This is added by the spilling pass in case of the JIT,
3172 * but we have to do it ourselves.
3174 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3178 case OP_MOVE_F_TO_I4: {
3179 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3182 case OP_MOVE_I4_TO_F: {
3183 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3186 case OP_MOVE_F_TO_I8: {
3187 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3190 case OP_MOVE_I8_TO_F: {
3191 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3224 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3225 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3227 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3228 CHECK_FAILURE (ctx);
3229 builder = ctx->builder;
3231 switch (ins->opcode) {
3234 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3238 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3242 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3246 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3250 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3254 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3258 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3262 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3266 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3270 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3274 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3278 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3282 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3286 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3290 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3293 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3296 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3300 g_assert_not_reached ();
3307 lhs = convert (ctx, lhs, LLVMFloatType ());
3308 rhs = convert (ctx, rhs, LLVMFloatType ());
3309 switch (ins->opcode) {
3311 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3314 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3317 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3320 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3323 g_assert_not_reached ();
3332 case OP_IREM_UN_IMM:
3334 case OP_IDIV_UN_IMM:
3340 case OP_ISHR_UN_IMM:
3349 case OP_LSHR_UN_IMM:
3355 case OP_SHR_UN_IMM: {
3358 if (spec [MONO_INST_SRC1] == 'l') {
3359 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3361 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3364 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3365 CHECK_FAILURE (ctx);
3366 builder = ctx->builder;
3368 #if SIZEOF_VOID_P == 4
3369 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3370 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3373 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3374 lhs = convert (ctx, lhs, IntPtrType ());
3375 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3376 switch (ins->opcode) {
3380 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3384 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3388 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3392 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3394 case OP_IDIV_UN_IMM:
3395 case OP_LDIV_UN_IMM:
3396 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3400 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3402 case OP_IREM_UN_IMM:
3403 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3408 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3412 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3416 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3421 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3426 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3428 case OP_ISHR_UN_IMM:
3429 /* This is used to implement conv.u4, so the lhs could be an i8 */
3430 lhs = convert (ctx, lhs, LLVMInt32Type ());
3431 imm = convert (ctx, imm, LLVMInt32Type ());
3432 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3434 case OP_LSHR_UN_IMM:
3436 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3439 g_assert_not_reached ();
3444 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3447 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3450 lhs = convert (ctx, lhs, LLVMDoubleType ());
3451 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3454 lhs = convert (ctx, lhs, LLVMFloatType ());
3455 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3458 guint32 v = 0xffffffff;
3459 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3463 guint64 v = 0xffffffffffffffffLL;
3464 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3467 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3469 LLVMValueRef v1, v2;
3471 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3472 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3473 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3478 case OP_ICONV_TO_I1:
3479 case OP_ICONV_TO_I2:
3480 case OP_ICONV_TO_I4:
3481 case OP_ICONV_TO_U1:
3482 case OP_ICONV_TO_U2:
3483 case OP_ICONV_TO_U4:
3484 case OP_LCONV_TO_I1:
3485 case OP_LCONV_TO_I2:
3486 case OP_LCONV_TO_U1:
3487 case OP_LCONV_TO_U2:
3488 case OP_LCONV_TO_U4: {
3491 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);
3493 /* Have to do two casts since our vregs have type int */
3494 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3496 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3498 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3501 case OP_ICONV_TO_I8:
3502 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3504 case OP_ICONV_TO_U8:
3505 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3507 case OP_FCONV_TO_I4:
3508 case OP_RCONV_TO_I4:
3509 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3511 case OP_FCONV_TO_I1:
3512 case OP_RCONV_TO_I1:
3513 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3515 case OP_FCONV_TO_U1:
3516 case OP_RCONV_TO_U1:
3517 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3519 case OP_FCONV_TO_I2:
3520 case OP_RCONV_TO_I2:
3521 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3523 case OP_FCONV_TO_U2:
3524 case OP_RCONV_TO_U2:
3525 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3527 case OP_FCONV_TO_I8:
3528 case OP_RCONV_TO_I8:
3529 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3532 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3534 case OP_ICONV_TO_R8:
3535 case OP_LCONV_TO_R8:
3536 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3538 case OP_ICONV_TO_R_UN:
3539 case OP_LCONV_TO_R_UN:
3540 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3542 #if SIZEOF_VOID_P == 4
3545 case OP_LCONV_TO_I4:
3546 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3548 case OP_ICONV_TO_R4:
3549 case OP_LCONV_TO_R4:
3550 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3552 values [ins->dreg] = v;
3554 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3556 case OP_FCONV_TO_R4:
3557 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3559 values [ins->dreg] = v;
3561 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3563 case OP_RCONV_TO_R8:
3564 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3566 case OP_RCONV_TO_R4:
3567 values [ins->dreg] = lhs;
3570 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3573 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3576 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3578 case OP_LOCALLOC_IMM: {
3581 guint32 size = ins->inst_imm;
3582 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3584 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3586 if (ins->flags & MONO_INST_INIT) {
3587 LLVMValueRef args [5];
3590 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3591 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3592 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3593 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3594 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3597 values [ins->dreg] = v;
3601 LLVMValueRef v, size;
3603 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), "");
3605 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3607 if (ins->flags & MONO_INST_INIT) {
3608 LLVMValueRef args [5];
3611 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3613 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3614 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3615 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3617 values [ins->dreg] = v;
3621 case OP_LOADI1_MEMBASE:
3622 case OP_LOADU1_MEMBASE:
3623 case OP_LOADI2_MEMBASE:
3624 case OP_LOADU2_MEMBASE:
3625 case OP_LOADI4_MEMBASE:
3626 case OP_LOADU4_MEMBASE:
3627 case OP_LOADI8_MEMBASE:
3628 case OP_LOADR4_MEMBASE:
3629 case OP_LOADR8_MEMBASE:
3630 case OP_LOAD_MEMBASE:
3638 LLVMValueRef base, index, addr;
3640 gboolean sext = FALSE, zext = FALSE;
3641 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3643 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3648 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)) {
3649 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3654 if (ins->inst_offset == 0) {
3656 } else if (ins->inst_offset % size != 0) {
3657 /* Unaligned load */
3658 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3659 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3661 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3662 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3666 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3668 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3670 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3672 * These will signal LLVM that these loads do not alias any stores, and
3673 * they can't fail, allowing them to be hoisted out of loops.
3675 set_invariant_load_flag (values [ins->dreg]);
3676 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3680 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3682 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3683 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3684 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3688 case OP_STOREI1_MEMBASE_REG:
3689 case OP_STOREI2_MEMBASE_REG:
3690 case OP_STOREI4_MEMBASE_REG:
3691 case OP_STOREI8_MEMBASE_REG:
3692 case OP_STORER4_MEMBASE_REG:
3693 case OP_STORER8_MEMBASE_REG:
3694 case OP_STORE_MEMBASE_REG: {
3696 LLVMValueRef index, addr;
3698 gboolean sext = FALSE, zext = FALSE;
3699 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3701 if (!values [ins->inst_destbasereg])
3702 LLVM_FAILURE (ctx, "inst_destbasereg");
3704 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3706 if (ins->inst_offset % size != 0) {
3707 /* Unaligned store */
3708 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3709 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3711 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3712 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3714 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3718 case OP_STOREI1_MEMBASE_IMM:
3719 case OP_STOREI2_MEMBASE_IMM:
3720 case OP_STOREI4_MEMBASE_IMM:
3721 case OP_STOREI8_MEMBASE_IMM:
3722 case OP_STORE_MEMBASE_IMM: {
3724 LLVMValueRef index, addr;
3726 gboolean sext = FALSE, zext = FALSE;
3727 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3729 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3731 if (ins->inst_offset % size != 0) {
3732 /* Unaligned store */
3733 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3734 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3736 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3737 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3739 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3744 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3746 case OP_OUTARG_VTRETADDR:
3754 case OP_VOIDCALL_MEMBASE:
3755 case OP_CALL_MEMBASE:
3756 case OP_LCALL_MEMBASE:
3757 case OP_FCALL_MEMBASE:
3758 case OP_RCALL_MEMBASE:
3759 case OP_VCALL_MEMBASE:
3760 case OP_VOIDCALL_REG:
3765 case OP_VCALL_REG: {
3766 process_call (ctx, bb, &builder, ins);
3767 CHECK_FAILURE (ctx);
3772 LLVMValueRef indexes [2];
3774 LLVMValueRef got_entry_addr;
3777 * FIXME: Can't allocate from the cfg mempool since that is freed if
3778 * the LLVM compile fails.
3780 ji = g_new0 (MonoJumpInfo, 1);
3781 ji->type = (MonoJumpInfoType)ins->inst_i1;
3782 ji->data.target = ins->inst_p0;
3784 ji = mono_aot_patch_info_dup (ji);
3786 ji->next = cfg->patch_info;
3787 cfg->patch_info = ji;
3789 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3790 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3791 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3793 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3794 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3795 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3797 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3798 set_invariant_load_flag (values [ins->dreg]);
3801 case OP_NOT_REACHED:
3802 LLVMBuildUnreachable (builder);
3803 has_terminator = TRUE;
3804 g_assert (bb->block_num < cfg->max_block_num);
3805 ctx->unreachable [bb->block_num] = TRUE;
3806 /* Might have instructions after this */
3808 MonoInst *next = ins->next;
3810 * FIXME: If later code uses the regs defined by these instructions,
3811 * compilation will fail.
3813 MONO_DELETE_INS (bb, next);
3817 MonoInst *var = ins->inst_p0;
3819 if (var->opcode == OP_VTARG_ADDR) {
3820 /* The variable contains the vtype address */
3821 values [ins->dreg] = values [var->dreg];
3823 values [ins->dreg] = addresses [var->dreg];
3828 LLVMValueRef args [1];
3830 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3831 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3835 LLVMValueRef args [1];
3837 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3838 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3842 LLVMValueRef args [1];
3845 /* This no longer seems to happen */
3847 * LLVM optimizes sqrt(nan) into undefined in
3848 * lib/Analysis/ConstantFolding.cpp
3849 * Also, sqrt(NegativeInfinity) is optimized into 0.
3851 LLVM_FAILURE (ctx, "sqrt");
3853 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3854 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3858 LLVMValueRef args [1];
3860 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3861 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3875 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3876 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3878 switch (ins->opcode) {
3881 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3885 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3889 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3893 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3896 g_assert_not_reached ();
3899 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3902 case OP_ATOMIC_EXCHANGE_I4:
3903 case OP_ATOMIC_EXCHANGE_I8: {
3904 LLVMValueRef args [2];
3907 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3908 t = LLVMInt32Type ();
3910 t = LLVMInt64Type ();
3912 g_assert (ins->inst_offset == 0);
3914 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3915 args [1] = convert (ctx, rhs, t);
3917 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3920 case OP_ATOMIC_ADD_I4:
3921 case OP_ATOMIC_ADD_I8: {
3922 LLVMValueRef args [2];
3925 if (ins->opcode == OP_ATOMIC_ADD_I4)
3926 t = LLVMInt32Type ();
3928 t = LLVMInt64Type ();
3930 g_assert (ins->inst_offset == 0);
3932 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3933 args [1] = convert (ctx, rhs, t);
3934 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3937 case OP_ATOMIC_CAS_I4:
3938 case OP_ATOMIC_CAS_I8: {
3939 LLVMValueRef args [3], val;
3942 if (ins->opcode == OP_ATOMIC_CAS_I4)
3943 t = LLVMInt32Type ();
3945 t = LLVMInt64Type ();
3947 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3949 args [1] = convert (ctx, values [ins->sreg3], t);
3951 args [2] = convert (ctx, values [ins->sreg2], t);
3952 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3953 /* cmpxchg returns a pair */
3954 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3957 case OP_MEMORY_BARRIER: {
3958 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3961 case OP_ATOMIC_LOAD_I1:
3962 case OP_ATOMIC_LOAD_I2:
3963 case OP_ATOMIC_LOAD_I4:
3964 case OP_ATOMIC_LOAD_I8:
3965 case OP_ATOMIC_LOAD_U1:
3966 case OP_ATOMIC_LOAD_U2:
3967 case OP_ATOMIC_LOAD_U4:
3968 case OP_ATOMIC_LOAD_U8:
3969 case OP_ATOMIC_LOAD_R4:
3970 case OP_ATOMIC_LOAD_R8: {
3971 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3974 gboolean sext, zext;
3976 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3977 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3978 LLVMValueRef index, addr;
3980 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3985 if (ins->inst_offset != 0) {
3986 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3987 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3992 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3994 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3997 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3999 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4002 case OP_ATOMIC_STORE_I1:
4003 case OP_ATOMIC_STORE_I2:
4004 case OP_ATOMIC_STORE_I4:
4005 case OP_ATOMIC_STORE_I8:
4006 case OP_ATOMIC_STORE_U1:
4007 case OP_ATOMIC_STORE_U2:
4008 case OP_ATOMIC_STORE_U4:
4009 case OP_ATOMIC_STORE_U8:
4010 case OP_ATOMIC_STORE_R4:
4011 case OP_ATOMIC_STORE_R8: {
4012 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
4015 gboolean sext, zext;
4017 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4018 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
4019 LLVMValueRef index, addr, value;
4021 if (!values [ins->inst_destbasereg])
4022 LLVM_FAILURE (ctx, "inst_destbasereg");
4024 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4026 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4027 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4028 value = convert (ctx, values [ins->sreg1], t);
4030 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
4033 case OP_RELAXED_NOP: {
4034 #if defined(TARGET_AMD64) || defined(TARGET_X86)
4035 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
4042 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
4044 // 257 == FS segment register
4045 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
4047 // 256 == GS segment register
4048 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4051 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
4052 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
4053 /* See mono_amd64_emit_tls_get () */
4054 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
4056 // 256 == GS segment register
4057 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4058 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
4060 LLVM_FAILURE (ctx, "opcode tls-get");
4065 case OP_TLS_GET_REG: {
4066 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4067 /* See emit_tls_get_reg () */
4068 // 256 == GS segment register
4069 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4070 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
4072 LLVM_FAILURE (ctx, "opcode tls-get");
4081 case OP_IADD_OVF_UN:
4083 case OP_ISUB_OVF_UN:
4085 case OP_IMUL_OVF_UN:
4086 #if SIZEOF_VOID_P == 8
4088 case OP_LADD_OVF_UN:
4090 case OP_LSUB_OVF_UN:
4092 case OP_LMUL_OVF_UN:
4095 LLVMValueRef args [2], val, ovf, func;
4097 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4098 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4099 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4101 val = LLVMBuildCall (builder, func, args, 2, "");
4102 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4103 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4104 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4105 CHECK_FAILURE (ctx);
4106 builder = ctx->builder;
4112 * We currently model them using arrays. Promotion to local vregs is
4113 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4114 * so we always have an entry in cfg->varinfo for them.
4115 * FIXME: Is this needed ?
4118 MonoClass *klass = ins->klass;
4119 LLVMValueRef args [5];
4123 LLVM_FAILURE (ctx, "!klass");
4127 if (!addresses [ins->dreg])
4128 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4129 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4130 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4131 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4133 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4134 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4135 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4138 case OP_DUMMY_VZERO:
4141 case OP_STOREV_MEMBASE:
4142 case OP_LOADV_MEMBASE:
4144 MonoClass *klass = ins->klass;
4145 LLVMValueRef src = NULL, dst, args [5];
4146 gboolean done = FALSE;
4150 LLVM_FAILURE (ctx, "!klass");
4154 if (mini_is_gsharedvt_klass (klass)) {
4156 LLVM_FAILURE (ctx, "gsharedvt");
4160 switch (ins->opcode) {
4161 case OP_STOREV_MEMBASE:
4162 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4163 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4164 /* Decomposed earlier */
4165 g_assert_not_reached ();
4168 if (!addresses [ins->sreg1]) {
4170 g_assert (values [ins->sreg1]);
4171 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));
4172 LLVMBuildStore (builder, values [ins->sreg1], dst);
4175 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4176 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4179 case OP_LOADV_MEMBASE:
4180 if (!addresses [ins->dreg])
4181 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4182 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4183 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4186 if (!addresses [ins->sreg1])
4187 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4188 if (!addresses [ins->dreg])
4189 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4190 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4191 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4194 g_assert_not_reached ();
4196 CHECK_FAILURE (ctx);
4203 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4204 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4206 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4207 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4208 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4211 case OP_LLVM_OUTARG_VT:
4212 if (!addresses [ins->sreg1]) {
4213 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4214 g_assert (values [ins->sreg1]);
4215 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4217 addresses [ins->dreg] = addresses [ins->sreg1];
4223 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4225 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4228 case OP_LOADX_MEMBASE: {
4229 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4232 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4233 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4236 case OP_STOREX_MEMBASE: {
4237 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4240 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4241 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4248 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4252 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4258 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4262 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4266 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4270 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4273 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4276 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4279 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4283 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4294 LLVMValueRef v = NULL;
4296 switch (ins->opcode) {
4301 t = LLVMVectorType (LLVMInt32Type (), 4);
4302 rt = LLVMVectorType (LLVMFloatType (), 4);
4308 t = LLVMVectorType (LLVMInt64Type (), 2);
4309 rt = LLVMVectorType (LLVMDoubleType (), 2);
4312 t = LLVMInt32Type ();
4313 rt = LLVMInt32Type ();
4314 g_assert_not_reached ();
4317 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4318 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4319 switch (ins->opcode) {
4322 v = LLVMBuildAnd (builder, lhs, rhs, "");
4326 v = LLVMBuildOr (builder, lhs, rhs, "");
4330 v = LLVMBuildXor (builder, lhs, rhs, "");
4334 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4337 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4361 case OP_PADDB_SAT_UN:
4362 case OP_PADDW_SAT_UN:
4363 case OP_PSUBB_SAT_UN:
4364 case OP_PSUBW_SAT_UN:
4372 case OP_PMULW_HIGH_UN: {
4373 LLVMValueRef args [2];
4378 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4385 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4389 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4397 case OP_EXTRACTX_U2:
4399 case OP_EXTRACT_U1: {
4401 gboolean zext = FALSE;
4403 t = simd_op_to_llvm_type (ins->opcode);
4405 switch (ins->opcode) {
4413 case OP_EXTRACTX_U2:
4418 t = LLVMInt32Type ();
4419 g_assert_not_reached ();
4422 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4423 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4425 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4434 case OP_EXPAND_R8: {
4435 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4436 LLVMValueRef mask [16], v;
4439 for (i = 0; i < 16; ++i)
4440 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4442 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4444 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4445 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4450 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4453 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4456 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4459 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4462 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4465 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4476 case OP_EXTRACT_MASK:
4483 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4485 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4491 LLVMValueRef args [3];
4495 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4497 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4502 /* This is only used for implementing shifts by non-immediate */
4503 values [ins->dreg] = lhs;
4514 LLVMValueRef args [3];
4517 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4519 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4530 case OP_PSHLQ_REG: {
4531 LLVMValueRef args [3];
4534 args [1] = values [ins->sreg2];
4536 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4543 case OP_PSHUFLEW_LOW:
4544 case OP_PSHUFLEW_HIGH: {
4546 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4547 int i, mask_size = 0;
4548 int imask = ins->inst_c0;
4550 /* Convert the x86 shuffle mask to LLVM's */
4551 switch (ins->opcode) {
4554 mask [0] = ((imask >> 0) & 3);
4555 mask [1] = ((imask >> 2) & 3);
4556 mask [2] = ((imask >> 4) & 3) + 4;
4557 mask [3] = ((imask >> 6) & 3) + 4;
4558 v1 = values [ins->sreg1];
4559 v2 = values [ins->sreg2];
4563 mask [0] = ((imask >> 0) & 1);
4564 mask [1] = ((imask >> 1) & 1) + 2;
4565 v1 = values [ins->sreg1];
4566 v2 = values [ins->sreg2];
4568 case OP_PSHUFLEW_LOW:
4570 mask [0] = ((imask >> 0) & 3);
4571 mask [1] = ((imask >> 2) & 3);
4572 mask [2] = ((imask >> 4) & 3);
4573 mask [3] = ((imask >> 6) & 3);
4578 v1 = values [ins->sreg1];
4579 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4581 case OP_PSHUFLEW_HIGH:
4587 mask [4] = 4 + ((imask >> 0) & 3);
4588 mask [5] = 4 + ((imask >> 2) & 3);
4589 mask [6] = 4 + ((imask >> 4) & 3);
4590 mask [7] = 4 + ((imask >> 6) & 3);
4591 v1 = values [ins->sreg1];
4592 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4596 mask [0] = ((imask >> 0) & 3);
4597 mask [1] = ((imask >> 2) & 3);
4598 mask [2] = ((imask >> 4) & 3);
4599 mask [3] = ((imask >> 6) & 3);
4600 v1 = values [ins->sreg1];
4601 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4604 g_assert_not_reached ();
4606 for (i = 0; i < mask_size; ++i)
4607 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4609 values [ins->dreg] =
4610 LLVMBuildShuffleVector (builder, v1, v2,
4611 LLVMConstVector (mask_values, mask_size), dname);
4615 case OP_UNPACK_LOWB:
4616 case OP_UNPACK_LOWW:
4617 case OP_UNPACK_LOWD:
4618 case OP_UNPACK_LOWQ:
4619 case OP_UNPACK_LOWPS:
4620 case OP_UNPACK_LOWPD:
4621 case OP_UNPACK_HIGHB:
4622 case OP_UNPACK_HIGHW:
4623 case OP_UNPACK_HIGHD:
4624 case OP_UNPACK_HIGHQ:
4625 case OP_UNPACK_HIGHPS:
4626 case OP_UNPACK_HIGHPD: {
4628 LLVMValueRef mask_values [16];
4629 int i, mask_size = 0;
4630 gboolean low = FALSE;
4632 switch (ins->opcode) {
4633 case OP_UNPACK_LOWB:
4637 case OP_UNPACK_LOWW:
4641 case OP_UNPACK_LOWD:
4642 case OP_UNPACK_LOWPS:
4646 case OP_UNPACK_LOWQ:
4647 case OP_UNPACK_LOWPD:
4651 case OP_UNPACK_HIGHB:
4654 case OP_UNPACK_HIGHW:
4657 case OP_UNPACK_HIGHD:
4658 case OP_UNPACK_HIGHPS:
4661 case OP_UNPACK_HIGHQ:
4662 case OP_UNPACK_HIGHPD:
4666 g_assert_not_reached ();
4670 for (i = 0; i < (mask_size / 2); ++i) {
4672 mask [(i * 2) + 1] = mask_size + i;
4675 for (i = 0; i < (mask_size / 2); ++i) {
4676 mask [(i * 2)] = (mask_size / 2) + i;
4677 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4681 for (i = 0; i < mask_size; ++i)
4682 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4684 values [ins->dreg] =
4685 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4686 LLVMConstVector (mask_values, mask_size), dname);
4691 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4692 LLVMValueRef v, val;
4694 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4695 val = LLVMConstNull (t);
4696 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4697 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4699 values [ins->dreg] = val;
4703 case OP_DUPPS_HIGH: {
4704 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4705 LLVMValueRef v1, v2, val;
4708 if (ins->opcode == OP_DUPPS_LOW) {
4709 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4710 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4712 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4713 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4715 val = LLVMConstNull (t);
4716 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4717 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4718 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4719 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4721 values [ins->dreg] = val;
4731 * EXCEPTION HANDLING
4733 case OP_IMPLICIT_EXCEPTION:
4734 /* This marks a place where an implicit exception can happen */
4735 if (bb->region != -1)
4736 LLVM_FAILURE (ctx, "implicit-exception");
4740 MonoMethodSignature *throw_sig;
4741 LLVMValueRef callee, arg;
4742 gboolean rethrow = (ins->opcode == OP_RETHROW);
4743 const char *icall_name;
4745 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4746 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4749 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4750 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4751 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4752 if (cfg->compile_aot) {
4753 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4755 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4759 * LLVM doesn't push the exception argument, so we need a different
4762 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4764 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4768 mono_memory_barrier ();
4770 ctx->lmodule->rethrow = callee;
4772 ctx->lmodule->throw = callee;
4774 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4775 emit_call (ctx, bb, &builder, callee, &arg, 1);
4778 case OP_CALL_HANDLER: {
4780 * We don't 'call' handlers, but instead simply branch to them.
4781 * The code generated by ENDFINALLY will branch back to us.
4783 LLVMBasicBlockRef noex_bb;
4785 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4787 bb_list = info->call_handler_return_bbs;
4790 * Set the indicator variable for the finally clause.
4792 lhs = info->finally_ind;
4794 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4796 /* Branch to the finally clause */
4797 LLVMBuildBr (builder, info->call_handler_target_bb);
4799 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4800 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4802 builder = ctx->builder = create_builder (ctx);
4803 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4805 bblocks [bb->block_num].end_bblock = noex_bb;
4808 case OP_START_HANDLER: {
4811 case OP_ENDFINALLY: {
4812 LLVMBasicBlockRef resume_bb;
4813 MonoBasicBlock *handler_bb;
4814 LLVMValueRef val, switch_ins, callee;
4818 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4819 g_assert (handler_bb);
4820 info = &bblocks [handler_bb->block_num];
4821 lhs = info->finally_ind;
4824 bb_list = info->call_handler_return_bbs;
4826 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4828 /* Load the finally variable */
4829 val = LLVMBuildLoad (builder, lhs, "");
4831 /* Reset the variable */
4832 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4834 /* Branch to either resume_bb, or to the bblocks in bb_list */
4835 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4837 * The other targets are added at the end to handle OP_CALL_HANDLER
4838 * opcodes processed later.
4840 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4842 builder = ctx->builder = create_builder (ctx);
4843 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4845 if (ctx->cfg->compile_aot) {
4846 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4848 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4850 LLVMBuildCall (builder, callee, NULL, 0, "");
4852 LLVMBuildUnreachable (builder);
4853 has_terminator = TRUE;
4859 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4860 LLVM_FAILURE (ctx, reason);
4865 /* Convert the value to the type required by phi nodes */
4866 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4867 if (!values [ins->dreg])
4869 values [ins->dreg] = addresses [ins->dreg];
4871 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4874 /* Add stores for volatile variables */
4875 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4876 emit_volatile_store (ctx, ins->dreg);
4879 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4880 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4882 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4883 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4884 LLVMBuildRetVoid (builder);
4887 if (bb == cfg->bb_entry)
4888 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4897 * mono_llvm_check_method_supported:
4899 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4900 * compiling a method twice.
4903 mono_llvm_check_method_supported (MonoCompile *cfg)
4907 if (cfg->method->save_lmf) {
4908 cfg->exception_message = g_strdup ("lmf");
4909 cfg->disable_llvm = TRUE;
4911 if (cfg->disable_llvm)
4915 * Nested clauses where one of the clauses is a finally clause is
4916 * not supported, because LLVM can't figure out the control flow,
4917 * probably because we resume exception handling by calling our
4918 * own function instead of using the 'resume' llvm instruction.
4920 for (i = 0; i < cfg->header->num_clauses; ++i) {
4921 for (j = 0; j < cfg->header->num_clauses; ++j) {
4922 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4923 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4925 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4926 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4927 cfg->exception_message = g_strdup ("nested clauses");
4928 cfg->disable_llvm = TRUE;
4933 if (cfg->disable_llvm)
4937 if (cfg->method->dynamic) {
4938 cfg->exception_message = g_strdup ("dynamic.");
4939 cfg->disable_llvm = TRUE;
4941 if (cfg->disable_llvm)
4946 * mono_llvm_emit_method:
4948 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4951 mono_llvm_emit_method (MonoCompile *cfg)
4954 MonoMethodSignature *sig;
4956 LLVMTypeRef method_type;
4957 LLVMValueRef method = NULL;
4959 LLVMValueRef *values;
4960 int i, max_block_num, bb_index;
4961 gboolean last = FALSE;
4962 GPtrArray *phi_values;
4963 LLVMCallInfo *linfo;
4965 LLVMModuleRef module;
4967 GPtrArray *bblock_list;
4968 MonoMethodHeader *header;
4969 MonoExceptionClause *clause;
4973 /* The code below might acquire the loader lock, so use it for global locking */
4974 mono_loader_lock ();
4976 /* Used to communicate with the callbacks */
4977 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4979 ctx = g_new0 (EmitContext, 1);
4981 ctx->mempool = cfg->mempool;
4984 * This maps vregs to the LLVM instruction defining them
4986 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4988 * This maps vregs for volatile variables to the LLVM instruction defining their
4991 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4992 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4993 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4994 phi_values = g_ptr_array_sized_new (256);
4996 * This signals whenever the vreg was defined by a phi node with no input vars
4997 * (i.e. all its input bblocks end with NOT_REACHABLE).
4999 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
5000 /* Whenever the bblock is unreachable */
5001 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
5003 bblock_list = g_ptr_array_sized_new (256);
5005 ctx->values = values;
5006 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
5007 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
5009 if (cfg->compile_aot) {
5010 ctx->lmodule = &aot_module;
5011 method_name = mono_aot_get_method_name (cfg);
5012 cfg->llvm_method_name = g_strdup (method_name);
5014 init_jit_module (cfg->domain);
5015 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
5016 method_name = mono_method_full_name (cfg->method, TRUE);
5019 module = ctx->module = ctx->lmodule->module;
5022 LLVM_FAILURE (ctx, "gsharedvt");
5026 static int count = 0;
5029 if (g_getenv ("LLVM_COUNT")) {
5030 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
5031 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
5035 if (count > atoi (g_getenv ("LLVM_COUNT")))
5036 LLVM_FAILURE (ctx, "");
5041 sig = mono_method_signature (cfg->method);
5044 linfo = mono_arch_get_llvm_call_info (cfg, sig);
5046 CHECK_FAILURE (ctx);
5049 linfo->rgctx_arg = TRUE;
5050 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
5051 CHECK_FAILURE (ctx);
5054 * This maps parameter indexes in the original signature to the indexes in
5055 * the LLVM signature.
5057 ctx->pindexes = sinfo.pindexes;
5059 method = LLVMAddFunction (module, method_name, method_type);
5060 ctx->lmethod = method;
5062 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
5063 LLVMSetLinkage (method, LLVMPrivateLinkage);
5065 LLVMAddFunctionAttr (method, LLVMUWTable);
5067 if (cfg->compile_aot) {
5068 LLVMSetLinkage (method, LLVMInternalLinkage);
5069 if (ctx->lmodule->external_symbols) {
5070 LLVMSetLinkage (method, LLVMExternalLinkage);
5071 LLVMSetVisibility (method, LLVMHiddenVisibility);
5074 LLVMSetLinkage (method, LLVMPrivateLinkage);
5077 if (cfg->method->save_lmf)
5078 LLVM_FAILURE (ctx, "lmf");
5080 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
5081 LLVM_FAILURE (ctx, "pinvoke signature");
5083 header = cfg->header;
5084 for (i = 0; i < header->num_clauses; ++i) {
5085 clause = &header->clauses [i];
5086 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5087 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5089 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5090 /* We can't handle inlined methods with clauses */
5091 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5093 if (linfo->rgctx_arg) {
5094 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5096 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5097 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5098 * CC_X86_64_Mono in X86CallingConv.td.
5100 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5101 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5103 if (cfg->vret_addr) {
5104 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5105 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5106 if (linfo->ret.storage == LLVMArgVtypeByRef) {
5107 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMStructRetAttribute);
5108 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMNoAliasAttribute);
5112 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5113 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5116 names = g_new (char *, sig->param_count);
5117 mono_method_get_param_names (cfg->method, (const char **) names);
5119 for (i = 0; i < sig->param_count; ++i) {
5122 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5123 if (names [i] && names [i][0] != '\0')
5124 name = g_strdup_printf ("arg_%s", names [i]);
5126 name = g_strdup_printf ("arg_%d", i);
5127 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5129 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5130 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5132 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByRef) {
5134 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
5139 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5140 ctx->minfo = mono_debug_lookup_method (cfg->method);
5141 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5145 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5146 max_block_num = MAX (max_block_num, bb->block_num);
5147 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5149 /* Add branches between non-consecutive bblocks */
5150 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5151 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5152 bb->next_bb != bb->last_ins->inst_false_bb) {
5154 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5155 inst->opcode = OP_BR;
5156 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5157 mono_bblock_add_inst (bb, inst);
5162 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5163 * was later optimized away, so clear these flags, and add them back for the still
5164 * present OP_LDADDR instructions.
5166 for (i = 0; i < cfg->next_vreg; ++i) {
5169 ins = get_vreg_to_inst (cfg, i);
5170 if (ins && ins != cfg->rgctx_var)
5171 ins->flags &= ~MONO_INST_INDIRECT;
5175 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5177 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5179 LLVMBuilderRef builder;
5181 char dname_buf[128];
5183 builder = create_builder (ctx);
5185 for (ins = bb->code; ins; ins = ins->next) {
5186 switch (ins->opcode) {
5191 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5193 CHECK_FAILURE (ctx);
5195 if (ins->opcode == OP_VPHI) {
5196 /* Treat valuetype PHI nodes as operating on the address itself */
5197 g_assert (ins->klass);
5198 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5202 * Have to precreate these, as they can be referenced by
5203 * earlier instructions.
5205 sprintf (dname_buf, "t%d", ins->dreg);
5207 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5209 if (ins->opcode == OP_VPHI)
5210 ctx->addresses [ins->dreg] = values [ins->dreg];
5212 g_ptr_array_add (phi_values, values [ins->dreg]);
5215 * Set the expected type of the incoming arguments since these have
5216 * to have the same type.
5218 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5219 int sreg1 = ins->inst_phi_args [i + 1];
5222 ctx->vreg_types [sreg1] = phi_type;
5227 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5236 * Create an ordering for bblocks, use the depth first order first, then
5237 * put the exception handling bblocks last.
5239 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5240 bb = cfg->bblocks [bb_index];
5241 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5242 g_ptr_array_add (bblock_list, bb);
5243 bblocks [bb->block_num].added = TRUE;
5247 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5248 if (!bblocks [bb->block_num].added)
5249 g_ptr_array_add (bblock_list, bb);
5253 * Second pass: generate code.
5255 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5256 bb = g_ptr_array_index (bblock_list, bb_index);
5258 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5261 process_bb (ctx, bb);
5262 CHECK_FAILURE (ctx);
5265 /* Add incoming phi values */
5266 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5267 GSList *l, *ins_list;
5269 ins_list = bblocks [bb->block_num].phi_nodes;
5271 for (l = ins_list; l; l = l->next) {
5272 PhiNode *node = l->data;
5273 MonoInst *phi = node->phi;
5274 int sreg1 = node->sreg;
5275 LLVMBasicBlockRef in_bb;
5280 in_bb = get_end_bb (ctx, node->in_bb);
5282 if (ctx->unreachable [node->in_bb->block_num])
5285 if (!values [sreg1])
5286 /* Can happen with values in EH clauses */
5287 LLVM_FAILURE (ctx, "incoming phi sreg1");
5289 if (phi->opcode == OP_VPHI) {
5290 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5291 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5293 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5295 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5296 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5297 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5302 /* Create the SWITCH statements for ENDFINALLY instructions */
5303 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5304 BBInfo *info = &bblocks [bb->block_num];
5306 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5307 LLVMValueRef switch_ins = l->data;
5308 GSList *bb_list = info->call_handler_return_bbs;
5310 for (i = 0; i < g_slist_length (bb_list); ++i)
5311 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5315 if (cfg->verbose_level > 1)
5316 mono_llvm_dump_value (method);
5318 if (cfg->compile_aot)
5319 mark_as_used (ctx->lmodule, method);
5321 if (cfg->compile_aot) {
5322 LLVMValueRef md_args [16];
5323 LLVMValueRef md_node;
5326 method_index = mono_aot_get_method_index (cfg->orig_method);
5327 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5328 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5329 md_node = LLVMMDNode (md_args, 2);
5330 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5331 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5334 if (cfg->compile_aot) {
5335 /* Don't generate native code, keep the LLVM IR */
5336 if (cfg->compile_aot && cfg->verbose_level)
5337 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5339 //LLVMVerifyFunction(method, 0);
5341 //LLVMVerifyFunction(method, 0);
5342 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5344 if (cfg->verbose_level > 1)
5345 mono_llvm_dump_value (method);
5347 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5349 /* Set by emit_cb */
5350 g_assert (cfg->code_len);
5352 /* FIXME: Free the LLVM IL for the function */
5355 if (ctx->lmodule->method_to_lmethod)
5356 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5363 /* Need to add unused phi nodes as they can be referenced by other values */
5364 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5365 LLVMBuilderRef builder;
5367 builder = create_builder (ctx);
5368 LLVMPositionBuilderAtEnd (builder, phi_bb);
5370 for (i = 0; i < phi_values->len; ++i) {
5371 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5372 if (LLVMGetInstructionParent (v) == NULL)
5373 LLVMInsertIntoBuilder (builder, v);
5376 LLVMDeleteFunction (method);
5381 g_free (ctx->addresses);
5382 g_free (ctx->vreg_types);
5383 g_free (ctx->vreg_cli_types);
5384 g_free (ctx->pindexes);
5385 g_free (ctx->is_dead);
5386 g_free (ctx->unreachable);
5387 g_ptr_array_free (phi_values, TRUE);
5388 g_free (ctx->bblocks);
5389 g_hash_table_destroy (ctx->region_to_handler);
5390 g_hash_table_destroy (ctx->clause_to_handler);
5391 g_free (method_name);
5392 g_ptr_array_free (bblock_list, TRUE);
5394 for (l = ctx->builders; l; l = l->next) {
5395 LLVMBuilderRef builder = l->data;
5396 LLVMDisposeBuilder (builder);
5401 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5403 mono_loader_unlock ();
5407 * mono_llvm_emit_call:
5409 * Same as mono_arch_emit_call () for LLVM.
5412 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5415 MonoMethodSignature *sig;
5416 int i, n, stack_size;
5421 sig = call->signature;
5422 n = sig->param_count + sig->hasthis;
5424 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5426 if (cfg->disable_llvm)
5429 if (sig->call_convention == MONO_CALL_VARARG) {
5430 cfg->exception_message = g_strdup ("varargs");
5431 cfg->disable_llvm = TRUE;
5434 for (i = 0; i < n; ++i) {
5437 ainfo = call->cinfo->args + i;
5439 in = call->args [i];
5441 /* Simply remember the arguments */
5442 switch (ainfo->storage) {
5444 case LLVMArgInFPReg: {
5445 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5448 opcode = mono_type_to_regmove (cfg, t);
5449 if (opcode == OP_FMOVE) {
5450 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5451 ins->dreg = mono_alloc_freg (cfg);
5452 } else if (opcode == OP_LMOVE) {
5453 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5454 ins->dreg = mono_alloc_lreg (cfg);
5456 MONO_INST_NEW (cfg, ins, OP_MOVE);
5457 ins->dreg = mono_alloc_ireg (cfg);
5459 ins->sreg1 = in->dreg;
5462 case LLVMArgVtypeByVal:
5463 case LLVMArgVtypeByRef:
5464 case LLVMArgVtypeInReg:
5465 case LLVMArgVtypeAsScalar:
5466 case LLVMArgAsIArgs:
5467 case LLVMArgAsFpArgs:
5468 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5469 ins->dreg = mono_alloc_ireg (cfg);
5470 ins->sreg1 = in->dreg;
5471 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5474 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5475 cfg->exception_message = g_strdup ("ainfo->storage");
5476 cfg->disable_llvm = TRUE;
5480 if (!cfg->disable_llvm) {
5481 MONO_ADD_INS (cfg->cbb, ins);
5482 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5487 static unsigned char*
5488 alloc_cb (LLVMValueRef function, int size)
5492 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5496 return mono_domain_code_reserve (cfg->domain, size);
5498 return mono_domain_code_reserve (mono_domain_get (), size);
5503 emitted_cb (LLVMValueRef function, void *start, void *end)
5507 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5509 cfg->code_len = (guint8*)end - (guint8*)start;
5513 exception_cb (void *data)
5516 MonoJitExceptionInfo *ei;
5517 guint32 ei_len, i, j, nested_len, nindex;
5518 gpointer *type_info;
5519 int this_reg, this_offset;
5521 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5525 * data points to a DWARF FDE structure, convert it to our unwind format and
5527 * An alternative would be to save it directly, and modify our unwinder to work
5530 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);
5531 if (cfg->verbose_level > 1)
5532 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5534 /* Count nested clauses */
5536 for (i = 0; i < ei_len; ++i) {
5537 gint32 cindex1 = *(gint32*)type_info [i];
5538 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5540 for (j = 0; j < cfg->header->num_clauses; ++j) {
5542 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5544 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5550 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5551 cfg->llvm_ex_info_len = ei_len + nested_len;
5552 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5553 /* Fill the rest of the information from the type info */
5554 for (i = 0; i < ei_len; ++i) {
5555 gint32 clause_index = *(gint32*)type_info [i];
5556 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5558 cfg->llvm_ex_info [i].flags = clause->flags;
5559 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5560 cfg->llvm_ex_info [i].clause_index = clause_index;
5564 * For nested clauses, the LLVM produced exception info associates the try interval with
5565 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5566 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5567 * and everything else from the nested clause.
5570 for (i = 0; i < ei_len; ++i) {
5571 gint32 cindex1 = *(gint32*)type_info [i];
5572 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5574 for (j = 0; j < cfg->header->num_clauses; ++j) {
5576 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5577 MonoJitExceptionInfo *nesting_ei, *nested_ei;
5579 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5580 /* clause1 is the nested clause */
5581 nested_ei = &cfg->llvm_ex_info [i];
5582 nesting_ei = &cfg->llvm_ex_info [nindex];
5585 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
5587 nesting_ei->flags = clause2->flags;
5588 nesting_ei->data.catch_class = clause2->data.catch_class;
5589 nesting_ei->clause_index = cindex2;
5593 g_assert (nindex == ei_len + nested_len);
5594 cfg->llvm_this_reg = this_reg;
5595 cfg->llvm_this_offset = this_offset;
5597 /* type_info [i] is cfg mempool allocated, no need to free it */
5604 dlsym_cb (const char *name, void **symbol)
5610 if (!strcmp (name, "__bzero")) {
5611 *symbol = (void*)bzero;
5613 current = mono_dl_open (NULL, 0, NULL);
5616 err = mono_dl_symbol (current, name, symbol);
5618 mono_dl_close (current);
5620 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5621 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5627 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5629 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5633 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5635 LLVMTypeRef param_types [4];
5637 param_types [0] = param_type1;
5638 param_types [1] = param_type2;
5640 AddFunc (module, name, ret_type, param_types, 2);
5644 add_intrinsics (LLVMModuleRef module)
5646 /* Emit declarations of instrinsics */
5648 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5649 * type doesn't seem to do any locking.
5652 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5654 memset_param_count = 5;
5655 memset_func_name = "llvm.memset.p0i8.i32";
5657 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5661 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5663 memcpy_param_count = 5;
5664 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5666 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5670 LLVMTypeRef params [] = { LLVMDoubleType () };
5672 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5673 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5674 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5676 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5677 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5681 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5682 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5683 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5685 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5686 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5687 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5688 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5689 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5690 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5691 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5695 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5696 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5697 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5699 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5700 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5701 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5702 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5703 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5704 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5709 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5711 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5714 /* SSE intrinsics */
5715 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5717 LLVMTypeRef ret_type, arg_types [16];
5720 ret_type = type_to_simd_type (MONO_TYPE_I4);
5721 arg_types [0] = ret_type;
5722 arg_types [1] = ret_type;
5723 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5724 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5726 ret_type = type_to_simd_type (MONO_TYPE_I2);
5727 arg_types [0] = ret_type;
5728 arg_types [1] = ret_type;
5729 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5730 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5731 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5732 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5733 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5734 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5735 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5736 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5737 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5738 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5740 ret_type = type_to_simd_type (MONO_TYPE_I1);
5741 arg_types [0] = ret_type;
5742 arg_types [1] = ret_type;
5743 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5744 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5745 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5746 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5747 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5748 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5749 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5751 ret_type = type_to_simd_type (MONO_TYPE_R8);
5752 arg_types [0] = ret_type;
5753 arg_types [1] = ret_type;
5754 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5755 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5756 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5757 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5758 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5760 ret_type = type_to_simd_type (MONO_TYPE_R4);
5761 arg_types [0] = ret_type;
5762 arg_types [1] = ret_type;
5763 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5764 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5765 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5766 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5767 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5770 ret_type = type_to_simd_type (MONO_TYPE_I1);
5771 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5772 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5773 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5774 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5775 ret_type = type_to_simd_type (MONO_TYPE_I2);
5776 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5777 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5778 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5779 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5782 ret_type = type_to_simd_type (MONO_TYPE_R8);
5783 arg_types [0] = ret_type;
5784 arg_types [1] = ret_type;
5785 arg_types [2] = LLVMInt8Type ();
5786 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5787 ret_type = type_to_simd_type (MONO_TYPE_R4);
5788 arg_types [0] = ret_type;
5789 arg_types [1] = ret_type;
5790 arg_types [2] = LLVMInt8Type ();
5791 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5793 /* Conversion ops */
5794 ret_type = type_to_simd_type (MONO_TYPE_R8);
5795 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5796 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5797 ret_type = type_to_simd_type (MONO_TYPE_R4);
5798 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5799 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5800 ret_type = type_to_simd_type (MONO_TYPE_I4);
5801 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5802 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5803 ret_type = type_to_simd_type (MONO_TYPE_I4);
5804 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5805 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5806 ret_type = type_to_simd_type (MONO_TYPE_R4);
5807 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5808 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5809 ret_type = type_to_simd_type (MONO_TYPE_R8);
5810 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5811 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5813 ret_type = type_to_simd_type (MONO_TYPE_I4);
5814 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5815 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5816 ret_type = type_to_simd_type (MONO_TYPE_I4);
5817 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5818 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5821 ret_type = type_to_simd_type (MONO_TYPE_R8);
5822 arg_types [0] = ret_type;
5823 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5824 ret_type = type_to_simd_type (MONO_TYPE_R4);
5825 arg_types [0] = ret_type;
5826 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5827 ret_type = type_to_simd_type (MONO_TYPE_R4);
5828 arg_types [0] = ret_type;
5829 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5830 ret_type = type_to_simd_type (MONO_TYPE_R4);
5831 arg_types [0] = ret_type;
5832 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5835 ret_type = type_to_simd_type (MONO_TYPE_I2);
5836 arg_types [0] = ret_type;
5837 arg_types [1] = LLVMInt32Type ();
5838 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5839 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5840 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5841 ret_type = type_to_simd_type (MONO_TYPE_I4);
5842 arg_types [0] = ret_type;
5843 arg_types [1] = LLVMInt32Type ();
5844 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5845 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5846 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5847 ret_type = type_to_simd_type (MONO_TYPE_I8);
5848 arg_types [0] = ret_type;
5849 arg_types [1] = LLVMInt32Type ();
5850 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5851 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5854 ret_type = LLVMInt32Type ();
5855 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5856 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5859 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5862 /* Load/Store intrinsics */
5864 LLVMTypeRef arg_types [5];
5868 for (i = 1; i <= 8; i *= 2) {
5869 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5870 arg_types [1] = LLVMInt32Type ();
5871 arg_types [2] = LLVMInt1Type ();
5872 arg_types [3] = LLVMInt32Type ();
5873 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5874 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5876 arg_types [0] = LLVMIntType (i * 8);
5877 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5878 arg_types [2] = LLVMInt32Type ();
5879 arg_types [3] = LLVMInt1Type ();
5880 arg_types [4] = LLVMInt32Type ();
5881 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5882 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5888 add_types (MonoLLVMModule *lmodule)
5890 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5894 mono_llvm_init (void)
5896 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5900 init_jit_module (MonoDomain *domain)
5902 MonoJitICallInfo *info;
5903 MonoJitDomainInfo *dinfo;
5904 MonoLLVMModule *module;
5907 dinfo = domain_jit_info (domain);
5908 if (dinfo->llvm_module)
5911 mono_loader_lock ();
5913 if (dinfo->llvm_module) {
5914 mono_loader_unlock ();
5918 module = g_new0 (MonoLLVMModule, 1);
5920 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5921 module->module = LLVMModuleCreateWithName (name);
5923 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5925 add_intrinsics (module->module);
5928 module->llvm_types = g_hash_table_new (NULL, NULL);
5930 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5932 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5934 mono_memory_barrier ();
5936 dinfo->llvm_module = module;
5938 mono_loader_unlock ();
5942 mono_llvm_cleanup (void)
5944 if (aot_module.module)
5945 LLVMDisposeModule (aot_module.module);
5947 LLVMContextDispose (LLVMGetGlobalContext ());
5951 mono_llvm_free_domain_info (MonoDomain *domain)
5953 MonoJitDomainInfo *info = domain_jit_info (domain);
5954 MonoLLVMModule *module = info->llvm_module;
5960 if (module->llvm_types)
5961 g_hash_table_destroy (module->llvm_types);
5963 mono_llvm_dispose_ee (module->mono_ee);
5965 if (module->bb_names) {
5966 for (i = 0; i < module->bb_names_len; ++i)
5967 g_free (module->bb_names [i]);
5968 g_free (module->bb_names);
5970 //LLVMDisposeModule (module->module);
5974 info->llvm_module = NULL;
5978 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link)
5980 MonoLLVMModule *lmodule = &aot_module;
5982 /* Delete previous module */
5983 if (lmodule->plt_entries)
5984 g_hash_table_destroy (lmodule->plt_entries);
5985 if (lmodule->module)
5986 LLVMDisposeModule (lmodule->module);
5988 memset (lmodule, 0, sizeof (aot_module));
5990 lmodule->module = LLVMModuleCreateWithName ("aot");
5991 lmodule->assembly = assembly;
5992 lmodule->global_prefix = g_strdup (global_prefix);
5993 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
5994 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
5995 lmodule->external_symbols = TRUE;
5996 lmodule->emit_dwarf = emit_dwarf;
5997 lmodule->static_link = static_link;
5998 /* The first few entries are reserved */
5999 lmodule->max_got_offset = 16;
6001 add_intrinsics (lmodule->module);
6002 add_types (lmodule);
6006 * We couldn't compute the type of the LLVM global representing the got because
6007 * its size is only known after all the methods have been emitted. So create
6008 * a dummy variable, and replace all uses it with the real got variable when
6009 * its size is known in mono_llvm_emit_aot_module ().
6012 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
6014 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
6015 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
6018 /* Add a dummy personality function */
6020 LLVMBasicBlockRef lbb;
6021 LLVMBuilderRef lbuilder;
6022 LLVMValueRef personality;
6024 personality = LLVMAddFunction (lmodule->module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
6025 LLVMSetLinkage (personality, LLVMInternalLinkage);
6026 lbb = LLVMAppendBasicBlock (personality, "BB0");
6027 lbuilder = LLVMCreateBuilder ();
6028 LLVMPositionBuilderAtEnd (lbuilder, lbb);
6029 LLVMBuildRetVoid (lbuilder);
6030 mark_as_used (lmodule, personality);
6033 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
6034 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
6035 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
6036 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
6040 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
6043 LLVMValueRef res, *vals;
6045 vals = g_new0 (LLVMValueRef, nvalues);
6046 for (i = 0; i < nvalues; ++i)
6047 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
6048 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
6054 * mono_llvm_emit_aot_file_info:
6056 * Emit the MonoAotFileInfo structure.
6057 * Same as emit_aot_file_info () in aot-compiler.c.
6060 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
6062 MonoLLVMModule *lmodule = &aot_module;
6064 /* Save these for later */
6065 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
6066 lmodule->has_jitted_code = has_jitted_code;
6070 * mono_llvm_emit_aot_data:
6072 * Emit the binary data DATA pointed to by symbol SYMBOL.
6075 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
6077 MonoLLVMModule *lmodule = &aot_module;
6081 type = LLVMArrayType (LLVMInt8Type (), data_len);
6082 d = LLVMAddGlobal (lmodule->module, type, symbol);
6083 LLVMSetVisibility (d, LLVMHiddenVisibility);
6084 LLVMSetLinkage (d, LLVMInternalLinkage);
6085 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
6086 mono_llvm_set_is_constant (d);
6089 /* Add a reference to a global defined in JITted code */
6091 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
6096 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
6097 v = LLVMAddGlobal (lmodule->module, type, s);
6103 emit_aot_file_info (MonoLLVMModule *lmodule)
6105 LLVMTypeRef file_info_type;
6106 LLVMTypeRef *eltypes, eltype;
6107 LLVMValueRef info_var;
6108 LLVMValueRef *fields;
6109 int i, nfields, tindex;
6110 MonoAotFileInfo *info;
6112 info = &lmodule->aot_info;
6114 /* Create an LLVM type to represent MonoAotFileInfo */
6116 eltypes = g_new (LLVMTypeRef, nfields);
6118 eltypes [tindex ++] = LLVMInt32Type ();
6119 eltypes [tindex ++] = LLVMInt32Type ();
6121 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6122 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
6124 for (i = 0; i < 13; ++i)
6125 eltypes [tindex ++] = LLVMInt32Type ();
6127 for (i = 0; i < 4; ++i)
6128 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6129 g_assert (tindex == nfields);
6130 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6131 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6133 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
6134 if (lmodule->static_link) {
6135 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
6136 LLVMSetLinkage (info_var, LLVMInternalLinkage);
6138 fields = g_new (LLVMValueRef, nfields);
6140 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6141 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6145 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6146 * for symbols defined in the .s file emitted by the aot compiler.
6148 eltype = eltypes [tindex];
6149 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
6150 fields [tindex ++] = lmodule->got_var;
6151 /* llc defines this directly */
6152 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
6153 if (TRUE || lmodule->has_jitted_code) {
6154 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
6155 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
6156 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
6158 fields [tindex ++] = LLVMConstNull (eltype);
6159 fields [tindex ++] = LLVMConstNull (eltype);
6160 fields [tindex ++] = LLVMConstNull (eltype);
6162 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
6163 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
6164 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
6165 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
6166 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
6167 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
6168 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
6169 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
6170 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
6171 /* Not needed (mem_end) */
6172 fields [tindex ++] = LLVMConstNull (eltype);
6173 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
6174 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
6175 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
6176 if (info->trampoline_size [0]) {
6177 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
6178 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
6179 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
6180 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
6182 fields [tindex ++] = LLVMConstNull (eltype);
6183 fields [tindex ++] = LLVMConstNull (eltype);
6184 fields [tindex ++] = LLVMConstNull (eltype);
6185 fields [tindex ++] = LLVMConstNull (eltype);
6187 if (lmodule->static_link)
6188 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
6190 fields [tindex ++] = LLVMConstNull (eltype);
6191 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
6192 if (TRUE || lmodule->has_jitted_code) {
6193 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
6194 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
6195 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
6196 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
6197 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
6198 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
6200 fields [tindex ++] = LLVMConstNull (eltype);
6201 fields [tindex ++] = LLVMConstNull (eltype);
6202 fields [tindex ++] = LLVMConstNull (eltype);
6203 fields [tindex ++] = LLVMConstNull (eltype);
6204 fields [tindex ++] = LLVMConstNull (eltype);
6205 fields [tindex ++] = LLVMConstNull (eltype);
6209 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6210 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6211 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6212 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6213 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6214 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6215 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6216 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6217 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6218 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6219 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6220 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6221 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6223 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6224 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6225 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6226 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6227 g_assert (tindex == nfields);
6229 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6231 if (lmodule->static_link) {
6235 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
6236 /* Get rid of characters which cannot occur in symbols */
6238 for (p = s; *p; ++p) {
6239 if (!(isalnum (*p) || *p == '_'))
6242 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
6244 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
6245 LLVMSetLinkage (var, LLVMExternalLinkage);
6250 * Emit the aot module into the LLVM bitcode file FILENAME.
6253 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6255 LLVMTypeRef got_type;
6256 LLVMValueRef real_got;
6257 MonoLLVMModule *module = &aot_module;
6260 * Create the real got variable and replace all uses of the dummy variable with
6263 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6264 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6265 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6266 if (module->external_symbols) {
6267 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6268 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6270 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6272 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6274 mark_as_used (&aot_module, real_got);
6276 /* Delete the dummy got so it doesn't become a global */
6277 LLVMDeleteGlobal (aot_module.got_var);
6278 aot_module.got_var = real_got;
6280 emit_llvm_used (&aot_module);
6281 emit_dbg_info (&aot_module, filename, cu_name);
6282 emit_aot_file_info (&aot_module);
6284 /* Replace PLT entries for directly callable methods with the methods themselves */
6286 GHashTableIter iter;
6288 LLVMValueRef callee;
6290 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6291 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6292 if (mono_aot_is_direct_callable (ji)) {
6293 LLVMValueRef lmethod;
6295 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6296 /* The types might not match because the caller might pass an rgctx */
6297 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6298 mono_llvm_replace_uses_of (callee, lmethod);
6299 mono_aot_mark_unused_llvm_plt_entry (ji);
6309 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6310 g_assert_not_reached ();
6315 LLVMWriteBitcodeToFile (aot_module.module, filename);
6320 md_string (const char *s)
6322 return LLVMMDString (s, strlen (s));
6325 /* Debugging support */
6328 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6330 LLVMModuleRef module = lmodule->module;
6331 LLVMValueRef args [16], cu_args [16], cu, ver;
6333 char *build_info, *s, *dir;
6336 * This can only be enabled when LLVM code is emitted into a separate object
6337 * file, since the AOT compiler also emits dwarf info,
6338 * and the abbrev indexes will not be correct since llvm has added its own
6341 if (!lmodule->emit_dwarf)
6345 * Emit dwarf info in the form of LLVM metadata. There is some
6346 * out-of-date documentation at:
6347 * http://llvm.org/docs/SourceLevelDebugging.html
6348 * but most of this was gathered from the llvm and
6353 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6354 /* CU name/compilation dir */
6355 dir = g_path_get_dirname (filename);
6356 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6357 args [1] = LLVMMDString (dir, strlen (dir));
6358 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6361 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6363 build_info = mono_get_runtime_build_info ();
6364 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6365 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6366 g_free (build_info);
6368 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6370 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6371 /* Runtime version */
6372 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6374 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6375 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6377 if (lmodule->subprogram_mds) {
6381 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6382 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6383 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6384 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6386 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6389 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6390 /* Imported modules */
6391 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6393 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6394 /* DebugEmissionKind = FullDebug */
6395 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6396 cu = LLVMMDNode (cu_args, n_cuargs);
6397 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6399 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6400 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6401 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6402 ver = LLVMMDNode (args, 3);
6403 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6405 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6406 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6407 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6408 ver = LLVMMDNode (args, 3);
6409 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6413 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6415 MonoLLVMModule *module = ctx->lmodule;
6416 MonoDebugMethodInfo *minfo = ctx->minfo;
6417 char *source_file, *dir, *filename;
6418 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6419 MonoSymSeqPoint *sym_seq_points;
6425 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6427 source_file = g_strdup ("<unknown>");
6428 dir = g_path_get_dirname (source_file);
6429 filename = g_path_get_basename (source_file);
6431 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6432 args [0] = md_string (filename);
6433 args [1] = md_string (dir);
6434 ctx_args [1] = LLVMMDNode (args, 2);
6435 ctx_md = LLVMMDNode (ctx_args, 2);
6437 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6438 type_args [1] = NULL;
6439 type_args [2] = NULL;
6440 type_args [3] = LLVMMDString ("", 0);
6441 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6442 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6443 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6444 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6445 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6446 type_args [9] = NULL;
6447 type_args [10] = NULL;
6448 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6449 type_args [12] = NULL;
6450 type_args [13] = NULL;
6451 type_args [14] = NULL;
6452 type_md = LLVMMDNode (type_args, 14);
6454 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6455 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6456 /* Source directory + file pair */
6457 args [0] = md_string (filename);
6458 args [1] = md_string (dir);
6459 md_args [1] = LLVMMDNode (args ,2);
6460 md_args [2] = ctx_md;
6461 md_args [3] = md_string (cfg->method->name);
6462 md_args [4] = md_string (name);
6463 md_args [5] = md_string (name);
6466 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6468 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6470 md_args [7] = type_md;
6472 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6474 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6476 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6477 /* Index into a virtual function */
6478 md_args [11] = NULL;
6479 md_args [12] = NULL;
6481 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6483 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6484 /* Pointer to LLVM function */
6485 md_args [15] = method;
6486 /* Function template parameter */
6487 md_args [16] = NULL;
6488 /* Function declaration descriptor */
6489 md_args [17] = NULL;
6490 /* List of function variables */
6491 md_args [18] = LLVMMDNode (args, 0);
6493 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6494 md = LLVMMDNode (md_args, 20);
6496 if (!module->subprogram_mds)
6497 module->subprogram_mds = g_ptr_array_new ();
6498 g_ptr_array_add (module->subprogram_mds, md);
6502 g_free (source_file);
6503 g_free (sym_seq_points);
6509 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6511 MonoCompile *cfg = ctx->cfg;
6513 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6514 MonoDebugSourceLocation *loc;
6515 LLVMValueRef loc_md, md_args [16];
6518 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6522 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6523 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6524 md_args [nmd_args ++] = ctx->dbg_md;
6525 md_args [nmd_args ++] = NULL;
6526 loc_md = LLVMMDNode (md_args, nmd_args);
6527 LLVMSetCurrentDebugLocation (builder, loc_md);
6528 mono_debug_symfile_free_location (loc);
6535 - Emit LLVM IR from the mono IR using the LLVM C API.
6536 - The original arch specific code remains, so we can fall back to it if we run
6537 into something we can't handle.
6541 A partial list of issues:
6542 - Handling of opcodes which can throw exceptions.
6544 In the mono JIT, these are implemented using code like this:
6551 push throw_pos - method
6552 call <exception trampoline>
6554 The problematic part is push throw_pos - method, which cannot be represented
6555 in the LLVM IR, since it does not support label values.
6556 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6557 be implemented in JIT mode ?
6558 -> a possible but slower implementation would use the normal exception
6559 throwing code but it would need to control the placement of the throw code
6560 (it needs to be exactly after the compare+branch).
6561 -> perhaps add a PC offset intrinsics ?
6563 - efficient implementation of .ovf opcodes.
6565 These are currently implemented as:
6566 <ins which sets the condition codes>
6569 Some overflow opcodes are now supported by LLVM SVN.
6571 - exception handling, unwinding.
6572 - SSA is disabled for methods with exception handlers
6573 - How to obtain unwind info for LLVM compiled methods ?
6574 -> this is now solved by converting the unwind info generated by LLVM
6576 - LLVM uses the c++ exception handling framework, while we use our home grown
6577 code, and couldn't use the c++ one:
6578 - its not supported under VC++, other exotic platforms.
6579 - it might be impossible to support filter clauses with it.
6583 The trampolines need a predictable call sequence, since they need to disasm
6584 the calling code to obtain register numbers / offsets.
6586 LLVM currently generates this code in non-JIT mode:
6587 mov -0x98(%rax),%eax
6589 Here, the vtable pointer is lost.
6590 -> solution: use one vtable trampoline per class.
6592 - passing/receiving the IMT pointer/RGCTX.
6593 -> solution: pass them as normal arguments ?
6597 LLVM does not allow the specification of argument registers etc. This means
6598 that all calls are made according to the platform ABI.
6600 - passing/receiving vtypes.
6602 Vtypes passed/received in registers are handled by the front end by using
6603 a signature with scalar arguments, and loading the parts of the vtype into those
6606 Vtypes passed on the stack are handled using the 'byval' attribute.
6610 Supported though alloca, we need to emit the load/store code.
6614 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6615 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6616 This is made easier because the IR is already in SSA form.
6617 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6618 types are frequently used incorrectly.
6623 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6624 it with the file containing the methods emitted by the JIT and the AOT data
6628 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6629 * - each bblock should end with a branch
6630 * - setting the return value, making cfg->ret non-volatile
6631 * - avoid some transformations in the JIT which make it harder for us to generate
6633 * - use pointer types to help optimizations.