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, state_poll;
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);
1189 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1191 ret_type = LLVMVoidType ();
1193 g_assert_not_reached ();
1196 case LLVMArgVtypeByVal:
1197 /* Vtype returned normally by val */
1199 case LLVMArgVtypeAsScalar:
1200 /* LLVM models this by returning an int */
1201 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1202 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1204 case LLVMArgFpStruct: {
1205 /* Vtype returned as a fp struct */
1206 LLVMTypeRef members [16];
1208 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1209 for (i = 0; i < cinfo->ret.nslots; ++i)
1210 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1211 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1214 case LLVMArgVtypeByRef:
1215 /* Vtype returned using a hidden argument */
1216 ret_type = LLVMVoidType ();
1219 if (mini_type_is_vtype (rtype)) {
1220 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1222 ret_type = LLVMVoidType ();
1228 pindexes = g_new0 (int, sig->param_count);
1229 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1231 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef) {
1233 * Has to be the first argument because of the sret argument attribute
1234 * FIXME: This might conflict with passing 'this' as the first argument, but
1235 * this is only used on arm64 which has a dedicated struct return register.
1238 sinfo->vret_arg_pindex = pindex;
1239 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1240 CHECK_FAILURE (ctx);
1241 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1244 if (cinfo && cinfo->rgctx_arg) {
1246 sinfo->rgctx_arg_pindex = pindex;
1247 param_types [pindex] = ctx->lmodule->ptr_type;
1250 if (cinfo && cinfo->imt_arg) {
1252 sinfo->imt_arg_pindex = pindex;
1253 param_types [pindex] = ctx->lmodule->ptr_type;
1257 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1258 vret_arg_pindex = pindex;
1259 if (cinfo->vret_arg_index == 1) {
1260 /* Add the slots consumed by the first argument */
1261 LLVMArgInfo *ainfo = &cinfo->args [0];
1262 switch (ainfo->storage) {
1263 case LLVMArgVtypeInReg:
1264 for (j = 0; j < 2; ++j) {
1265 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1275 sinfo->vret_arg_pindex = vret_arg_pindex;
1278 if (vretaddr && vret_arg_pindex == pindex)
1279 param_types [pindex ++] = IntPtrType ();
1282 sinfo->this_arg_pindex = pindex;
1283 param_types [pindex ++] = ThisType ();
1285 if (vretaddr && vret_arg_pindex == pindex)
1286 param_types [pindex ++] = IntPtrType ();
1287 for (i = 0; i < sig->param_count; ++i) {
1288 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1290 if (vretaddr && vret_arg_pindex == pindex)
1291 param_types [pindex ++] = IntPtrType ();
1292 pindexes [i] = pindex;
1295 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1299 switch (ainfo->storage) {
1300 case LLVMArgVtypeInReg:
1301 for (j = 0; j < 2; ++j) {
1302 switch (ainfo->pair_storage [j]) {
1304 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1309 g_assert_not_reached ();
1313 case LLVMArgVtypeByVal:
1314 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1315 CHECK_FAILURE (ctx);
1316 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1319 case LLVMArgAsIArgs:
1320 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1323 case LLVMArgVtypeByRef:
1324 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1325 CHECK_FAILURE (ctx);
1326 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1329 case LLVMArgAsFpArgs: {
1332 for (j = 0; j < ainfo->nslots; ++j)
1333 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1334 pindex += ainfo->nslots;
1337 case LLVMArgVtypeAsScalar:
1338 g_assert_not_reached ();
1341 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1345 if (vretaddr && vret_arg_pindex == pindex)
1346 param_types [pindex ++] = IntPtrType ();
1348 CHECK_FAILURE (ctx);
1350 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1351 g_free (param_types);
1354 sinfo->pindexes = pindexes;
1362 g_free (param_types);
1368 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1370 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1374 * LLVMFunctionType1:
1376 * Create an LLVM function type from the arguments.
1378 static G_GNUC_UNUSED LLVMTypeRef
1379 LLVMFunctionType1(LLVMTypeRef ReturnType,
1380 LLVMTypeRef ParamType1,
1383 LLVMTypeRef param_types [1];
1385 param_types [0] = ParamType1;
1387 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1391 * LLVMFunctionType2:
1393 * Create an LLVM function type from the arguments.
1395 static G_GNUC_UNUSED LLVMTypeRef
1396 LLVMFunctionType2(LLVMTypeRef ReturnType,
1397 LLVMTypeRef ParamType1,
1398 LLVMTypeRef ParamType2,
1401 LLVMTypeRef param_types [2];
1403 param_types [0] = ParamType1;
1404 param_types [1] = ParamType2;
1406 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1410 * LLVMFunctionType3:
1412 * Create an LLVM function type from the arguments.
1414 static G_GNUC_UNUSED LLVMTypeRef
1415 LLVMFunctionType3(LLVMTypeRef ReturnType,
1416 LLVMTypeRef ParamType1,
1417 LLVMTypeRef ParamType2,
1418 LLVMTypeRef ParamType3,
1421 LLVMTypeRef param_types [3];
1423 param_types [0] = ParamType1;
1424 param_types [1] = ParamType2;
1425 param_types [2] = ParamType3;
1427 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1433 * Create an LLVM builder and remember it so it can be freed later.
1435 static LLVMBuilderRef
1436 create_builder (EmitContext *ctx)
1438 LLVMBuilderRef builder = LLVMCreateBuilder ();
1440 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1446 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1448 char *callee_name = mono_aot_get_plt_symbol (type, data);
1449 LLVMValueRef callee;
1450 MonoJumpInfo *ji = NULL;
1455 if (ctx->cfg->compile_aot)
1456 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1457 mono_add_patch_info (ctx->cfg, 0, type, data);
1460 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1462 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1464 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1466 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1469 if (ctx->cfg->compile_aot) {
1470 ji = g_new0 (MonoJumpInfo, 1);
1472 ji->data.target = data;
1474 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1481 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1483 MonoMethodHeader *header = cfg->header;
1484 MonoExceptionClause *clause;
1488 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1489 return (bb->region >> 8) - 1;
1492 for (i = 0; i < header->num_clauses; ++i) {
1493 clause = &header->clauses [i];
1495 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1503 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1505 LLVMValueRef md_arg;
1508 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1509 md_arg = LLVMMDString ("mono", 4);
1510 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1514 set_invariant_load_flag (LLVMValueRef v)
1516 LLVMValueRef md_arg;
1518 const char *flag_name;
1520 // FIXME: Cache this
1521 flag_name = "invariant.load";
1522 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1523 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1524 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1530 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1534 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1536 MonoCompile *cfg = ctx->cfg;
1538 LLVMBuilderRef builder = *builder_ref;
1541 clause_index = get_handler_clause (cfg, bb);
1543 if (clause_index != -1) {
1544 MonoMethodHeader *header = cfg->header;
1545 MonoExceptionClause *ec = &header->clauses [clause_index];
1546 MonoBasicBlock *tblock;
1547 LLVMBasicBlockRef ex_bb, noex_bb;
1550 * Have to use an invoke instead of a call, branching to the
1551 * handler bblock of the clause containing this bblock.
1554 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1556 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1559 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1561 ex_bb = get_bb (ctx, tblock);
1563 noex_bb = gen_bb (ctx, "NOEX_BB");
1566 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1568 builder = ctx->builder = create_builder (ctx);
1569 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1571 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1573 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1574 ctx->builder = builder;
1577 *builder_ref = ctx->builder;
1583 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1585 const char *intrins_name;
1586 LLVMValueRef args [16], res;
1587 LLVMTypeRef addr_type;
1589 if (is_faulting && bb->region != -1) {
1590 LLVMAtomicOrdering ordering;
1593 case LLVM_BARRIER_NONE:
1594 ordering = LLVMAtomicOrderingNotAtomic;
1596 case LLVM_BARRIER_ACQ:
1597 ordering = LLVMAtomicOrderingAcquire;
1599 case LLVM_BARRIER_SEQ:
1600 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1603 g_assert_not_reached ();
1608 * We handle loads which can fault by calling a mono specific intrinsic
1609 * using an invoke, so they are handled properly inside try blocks.
1610 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1611 * are marked with IntrReadArgMem.
1615 intrins_name = "llvm.mono.load.i8.p0i8";
1618 intrins_name = "llvm.mono.load.i16.p0i16";
1621 intrins_name = "llvm.mono.load.i32.p0i32";
1624 intrins_name = "llvm.mono.load.i64.p0i64";
1627 g_assert_not_reached ();
1630 addr_type = LLVMTypeOf (addr);
1631 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1632 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1635 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1636 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1637 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1638 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1640 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1641 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1642 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1643 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1650 * We emit volatile loads for loads which can fault, because otherwise
1651 * LLVM will generate invalid code when encountering a load from a
1654 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1656 /* Mark it with a custom metadata */
1659 set_metadata_flag (res, "mono.faulting.load");
1667 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1669 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1673 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1675 const char *intrins_name;
1676 LLVMValueRef args [16];
1678 if (is_faulting && bb->region != -1) {
1679 LLVMAtomicOrdering ordering;
1682 case LLVM_BARRIER_NONE:
1683 ordering = LLVMAtomicOrderingNotAtomic;
1685 case LLVM_BARRIER_REL:
1686 ordering = LLVMAtomicOrderingRelease;
1688 case LLVM_BARRIER_SEQ:
1689 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1692 g_assert_not_reached ();
1698 intrins_name = "llvm.mono.store.i8.p0i8";
1701 intrins_name = "llvm.mono.store.i16.p0i16";
1704 intrins_name = "llvm.mono.store.i32.p0i32";
1707 intrins_name = "llvm.mono.store.i64.p0i64";
1710 g_assert_not_reached ();
1713 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1714 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1715 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1720 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1721 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1722 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1723 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1725 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1730 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1732 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1736 * emit_cond_system_exception:
1738 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1739 * Might set the ctx exception.
1742 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1744 LLVMBasicBlockRef ex_bb, noex_bb;
1745 LLVMBuilderRef builder;
1746 MonoClass *exc_class;
1747 LLVMValueRef args [2];
1749 ex_bb = gen_bb (ctx, "EX_BB");
1750 noex_bb = gen_bb (ctx, "NOEX_BB");
1752 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1754 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1755 g_assert (exc_class);
1757 /* Emit exception throwing code */
1758 builder = create_builder (ctx);
1759 LLVMPositionBuilderAtEnd (builder, ex_bb);
1761 if (!ctx->lmodule->throw_corlib_exception) {
1762 LLVMValueRef callee;
1764 const char *icall_name;
1766 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1767 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1768 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1769 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1770 /* This will become i8* */
1771 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1772 sig = sig_to_llvm_sig (ctx, throw_sig);
1774 if (ctx->cfg->compile_aot) {
1775 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1777 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1780 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1781 * - On x86, LLVM generated code doesn't push the arguments
1782 * - The trampoline takes the throw address as an arguments, not a pc offset.
1784 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1787 mono_memory_barrier ();
1788 ctx->lmodule->throw_corlib_exception = callee;
1791 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1792 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1794 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1797 * The LLVM mono branch contains changes so a block address can be passed as an
1798 * argument to a call.
1800 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1801 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1803 LLVMBuildUnreachable (builder);
1805 ctx->builder = create_builder (ctx);
1806 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1808 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1815 * emit_args_to_vtype:
1817 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1820 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1822 int j, size, nslots;
1824 size = get_vtype_size (t);
1826 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1827 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1830 if (ainfo->storage == LLVMArgAsFpArgs)
1831 nslots = ainfo->nslots;
1835 for (j = 0; j < nslots; ++j) {
1836 LLVMValueRef index [2], addr, daddr;
1837 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1838 LLVMTypeRef part_type;
1840 if (ainfo->pair_storage [j] == LLVMArgNone)
1843 switch (ainfo->pair_storage [j]) {
1844 case LLVMArgInIReg: {
1845 part_type = LLVMIntType (part_size * 8);
1846 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1847 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1848 addr = LLVMBuildGEP (builder, address, index, 1, "");
1850 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1851 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1852 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1854 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1857 case LLVMArgInFPReg: {
1858 LLVMTypeRef arg_type;
1860 if (ainfo->esize == 8)
1861 arg_type = LLVMDoubleType ();
1863 arg_type = LLVMFloatType ();
1865 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1866 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1867 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1868 LLVMBuildStore (builder, args [j], addr);
1874 g_assert_not_reached ();
1877 size -= sizeof (gpointer);
1882 * emit_vtype_to_args:
1884 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1885 * into ARGS, and the number of arguments into NARGS.
1888 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1891 int j, size, nslots;
1892 LLVMTypeRef arg_type;
1894 size = get_vtype_size (t);
1896 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1897 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1899 if (ainfo->storage == LLVMArgAsFpArgs)
1900 nslots = ainfo->nslots;
1903 for (j = 0; j < nslots; ++j) {
1904 LLVMValueRef index [2], addr, daddr;
1905 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1907 if (ainfo->pair_storage [j] == LLVMArgNone)
1910 switch (ainfo->pair_storage [j]) {
1912 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1913 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1914 addr = LLVMBuildGEP (builder, address, index, 1, "");
1916 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1917 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1918 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1920 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1922 case LLVMArgInFPReg:
1923 if (ainfo->esize == 8)
1924 arg_type = LLVMDoubleType ();
1926 arg_type = LLVMFloatType ();
1927 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1928 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1929 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1930 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1935 g_assert_not_reached ();
1937 size -= sizeof (gpointer);
1944 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1947 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1948 * get executed every time control reaches them.
1950 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1952 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1953 return ctx->last_alloca;
1957 build_alloca (EmitContext *ctx, MonoType *t)
1959 MonoClass *k = mono_class_from_mono_type (t);
1962 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1965 align = mono_class_min_align (k);
1967 /* Sometimes align is not a power of 2 */
1968 while (mono_is_power_of_two (align) == -1)
1971 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1975 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1978 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1981 lmodule->used = g_ptr_array_sized_new (16);
1982 g_ptr_array_add (lmodule->used, global);
1986 emit_llvm_used (MonoLLVMModule *lmodule)
1988 LLVMModuleRef module = lmodule->module;
1989 LLVMTypeRef used_type;
1990 LLVMValueRef used, *used_elem;
1996 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1997 used = LLVMAddGlobal (module, used_type, "llvm.used");
1998 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1999 for (i = 0; i < lmodule->used->len; ++i)
2000 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2001 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
2002 LLVMSetLinkage (used, LLVMAppendingLinkage);
2003 LLVMSetSection (used, "llvm.metadata");
2007 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2009 gboolean need_div_check = FALSE;
2011 #ifdef MONO_ARCH_NEED_DIV_CHECK
2012 need_div_check = TRUE;
2015 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2016 need_div_check = TRUE;
2018 if (!need_div_check)
2021 switch (ins->opcode) {
2034 case OP_IDIV_UN_IMM:
2035 case OP_LDIV_UN_IMM:
2036 case OP_IREM_UN_IMM:
2037 case OP_LREM_UN_IMM: {
2039 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2040 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2042 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2043 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2044 CHECK_FAILURE (ctx);
2045 builder = ctx->builder;
2047 /* b == -1 && a == 0x80000000 */
2049 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2050 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2051 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2053 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2054 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2055 CHECK_FAILURE (ctx);
2056 builder = ctx->builder;
2071 * Emit code to load/convert arguments.
2074 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2077 MonoCompile *cfg = ctx->cfg;
2078 MonoMethodSignature *sig = ctx->sig;
2079 LLVMCallInfo *linfo = ctx->linfo;
2082 ctx->alloca_builder = create_builder (ctx);
2085 * Handle indirect/volatile variables by allocating memory for them
2086 * using 'alloca', and storing their address in a temporary.
2088 for (i = 0; i < cfg->num_varinfo; ++i) {
2089 MonoInst *var = cfg->varinfo [i];
2092 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (var->inst_vtype)) {
2093 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2094 CHECK_FAILURE (ctx);
2095 /* Could be already created by an OP_VPHI */
2096 if (!ctx->addresses [var->dreg])
2097 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2098 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2102 for (i = 0; i < sig->param_count; ++i) {
2103 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2104 int reg = cfg->args [i + sig->hasthis]->dreg;
2106 switch (ainfo->storage) {
2107 case LLVMArgVtypeInReg:
2108 case LLVMArgAsFpArgs: {
2109 LLVMValueRef args [8];
2112 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2113 memset (args, 0, sizeof (args));
2114 pindex = ctx->pindexes [i];
2115 if (ainfo->storage == LLVMArgVtypeInReg) {
2116 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2117 if (ainfo->pair_storage [1] != LLVMArgNone)
2118 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2120 g_assert (ainfo->nslots <= 8);
2121 for (j = 0; j < ainfo->nslots; ++j)
2122 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2124 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2126 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2128 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2129 /* Treat these as normal values */
2130 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2134 case LLVMArgVtypeByVal: {
2135 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2137 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2138 /* Treat these as normal values */
2139 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2143 case LLVMArgVtypeByRef: {
2144 /* The argument is passed by ref */
2145 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2148 case LLVMArgAsIArgs: {
2149 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2151 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2153 /* The argument is received as an array of ints, store it into the real argument */
2154 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2157 case LLVMArgVtypeAsScalar:
2158 g_assert_not_reached ();
2161 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]));
2167 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2169 emit_volatile_store (ctx, cfg->args [0]->dreg);
2170 for (i = 0; i < sig->param_count; ++i)
2171 if (!mini_type_is_vtype (sig->params [i]))
2172 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2174 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2175 LLVMValueRef this_alloc;
2178 * The exception handling code needs the location where the this argument was
2179 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2180 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2181 * location into the LSDA.
2183 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2184 /* This volatile store will keep the alloca alive */
2185 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2187 set_metadata_flag (this_alloc, "mono.this");
2190 if (cfg->rgctx_var) {
2191 LLVMValueRef rgctx_alloc, store;
2194 * We handle the rgctx arg similarly to the this pointer.
2196 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2197 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2198 /* This volatile store will keep the alloca alive */
2199 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2201 set_metadata_flag (rgctx_alloc, "mono.this");
2204 /* Compute nesting between clauses */
2205 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2206 for (i = 0; i < cfg->header->num_clauses; ++i) {
2207 for (j = 0; j < cfg->header->num_clauses; ++j) {
2208 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2209 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2211 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2212 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2217 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2218 * it needs to continue normally, or return back to the exception handling system.
2220 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2224 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2227 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2228 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2229 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2231 if (bb->in_scount == 0) {
2234 sprintf (name, "finally_ind_bb%d", bb->block_num);
2235 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2236 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2238 ctx->bblocks [bb->block_num].finally_ind = val;
2240 /* Create a variable to hold the exception var */
2242 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2246 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2247 * LLVM bblock containing a landing pad causes problems for the
2248 * LLVM optimizer passes.
2250 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2251 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2259 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2261 MonoCompile *cfg = ctx->cfg;
2262 LLVMModuleRef module = ctx->module;
2263 LLVMValueRef *values = ctx->values;
2264 LLVMValueRef *addresses = ctx->addresses;
2265 MonoCallInst *call = (MonoCallInst*)ins;
2266 MonoMethodSignature *sig = call->signature;
2267 LLVMValueRef callee = NULL, lcall;
2269 LLVMCallInfo *cinfo;
2273 LLVMTypeRef llvm_sig;
2275 gboolean virtual, calli;
2276 LLVMBuilderRef builder = *builder_ref;
2279 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2280 LLVM_FAILURE (ctx, "non-default callconv");
2282 cinfo = call->cinfo;
2283 if (call->rgctx_arg_reg)
2284 cinfo->rgctx_arg = TRUE;
2285 if (call->imt_arg_reg)
2286 cinfo->imt_arg = TRUE;
2288 vretaddr = cinfo && (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef);
2290 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2291 CHECK_FAILURE (ctx);
2293 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);
2294 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);
2296 /* FIXME: Avoid creating duplicate methods */
2298 if (ins->flags & MONO_INST_HAS_METHOD) {
2302 if (cfg->compile_aot) {
2303 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2305 LLVM_FAILURE (ctx, "can't encode patch");
2307 callee = LLVMAddFunction (module, "", llvm_sig);
2310 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2312 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2316 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2317 /* LLVM miscompiles async methods */
2318 LLVM_FAILURE (ctx, "#13734");
2321 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2327 memset (&ji, 0, sizeof (ji));
2328 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2329 ji.data.target = info->name;
2331 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2333 if (cfg->compile_aot) {
2334 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2336 LLVM_FAILURE (ctx, "can't encode patch");
2338 callee = LLVMAddFunction (module, "", llvm_sig);
2339 target = (gpointer)mono_icall_get_wrapper (info);
2340 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2343 if (cfg->compile_aot) {
2345 if (cfg->abs_patches) {
2346 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2348 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2350 LLVM_FAILURE (ctx, "can't encode patch");
2354 LLVM_FAILURE (ctx, "aot");
2356 callee = LLVMAddFunction (module, "", llvm_sig);
2358 if (cfg->abs_patches) {
2359 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2362 * FIXME: Some trampolines might have
2363 * their own calling convention on some platforms.
2365 #ifndef TARGET_AMD64
2366 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2367 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2368 LLVM_FAILURE (ctx, "trampoline with own cconv");
2370 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2371 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2375 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2381 int size = sizeof (gpointer);
2384 g_assert (ins->inst_offset % size == 0);
2385 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2387 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2389 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2391 if (ins->flags & MONO_INST_HAS_METHOD) {
2396 * Collect and convert arguments
2398 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2399 len = sizeof (LLVMValueRef) * nargs;
2400 args = alloca (len);
2401 memset (args, 0, len);
2402 l = call->out_ireg_args;
2404 if (call->rgctx_arg_reg) {
2405 g_assert (values [call->rgctx_arg_reg]);
2406 g_assert (sinfo.rgctx_arg_pindex < nargs);
2408 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2409 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2410 * it using a volatile load.
2413 if (!ctx->imt_rgctx_loc)
2414 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2415 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2416 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2418 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2421 if (call->imt_arg_reg) {
2422 g_assert (values [call->imt_arg_reg]);
2423 g_assert (sinfo.imt_arg_pindex < nargs);
2425 if (!ctx->imt_rgctx_loc)
2426 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2427 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2428 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2430 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2434 if (!addresses [call->inst.dreg])
2435 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2436 g_assert (sinfo.vret_arg_pindex < nargs);
2437 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
2438 args [sinfo.vret_arg_pindex] = addresses [call->inst.dreg];
2440 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2443 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2446 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2450 pindex = sinfo.this_arg_pindex;
2452 pindex = sinfo.pindexes [i - 1];
2454 pindex = sinfo.pindexes [i];
2457 regpair = (guint32)(gssize)(l->data);
2458 reg = regpair & 0xffffff;
2459 args [pindex] = values [reg];
2460 switch (ainfo->storage) {
2461 case LLVMArgVtypeInReg:
2462 case LLVMArgAsFpArgs: {
2465 g_assert (addresses [reg]);
2466 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2470 // FIXME: Get rid of the VMOVE
2473 case LLVMArgVtypeByVal:
2474 g_assert (addresses [reg]);
2475 args [pindex] = addresses [reg];
2477 case LLVMArgVtypeByRef:
2478 g_assert (addresses [reg]);
2479 args [pindex] = addresses [reg];
2481 case LLVMArgAsIArgs:
2482 g_assert (addresses [reg]);
2483 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2485 case LLVMArgVtypeAsScalar:
2486 g_assert_not_reached ();
2489 g_assert (args [pindex]);
2490 if (i == 0 && sig->hasthis)
2491 args [pindex] = convert (ctx, args [pindex], ThisType ());
2493 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2496 g_assert (pindex <= nargs);
2501 // FIXME: Align call sites
2507 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2510 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2512 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2513 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2515 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2516 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2518 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2520 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
2521 LLVMAddInstrAttribute (lcall, 1 + sinfo.vret_arg_pindex, LLVMStructRetAttribute);
2522 if (call->rgctx_arg_reg)
2523 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2524 if (call->imt_arg_reg)
2525 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2527 /* Add byval attributes if needed */
2528 for (i = 0; i < sig->param_count; ++i) {
2529 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2531 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2532 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2537 * Convert the result
2540 switch (cinfo->ret.storage) {
2541 case LLVMArgVtypeInReg: {
2542 LLVMValueRef regs [2];
2544 if (LLVMTypeOf (lcall) == LLVMVoidType ())
2548 if (!addresses [ins->dreg])
2549 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2551 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2552 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2553 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2554 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2557 case LLVMArgVtypeByVal:
2558 if (!addresses [call->inst.dreg])
2559 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2560 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2562 case LLVMArgFpStruct:
2563 if (!addresses [call->inst.dreg])
2564 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2565 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2567 case LLVMArgVtypeAsScalar:
2568 if (!addresses [call->inst.dreg])
2569 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2570 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2573 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2574 /* If the method returns an unsigned value, need to zext it */
2575 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));
2579 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2580 /* If the method returns an unsigned value, need to zext it */
2581 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));
2585 if (!addresses [call->inst.dreg])
2586 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2587 g_assert (sinfo.vret_arg_pindex < nargs);
2588 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2591 *builder_ref = ctx->builder;
2593 g_free (sinfo.pindexes);
2601 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2603 MonoCompile *cfg = ctx->cfg;
2604 LLVMValueRef *values = ctx->values;
2605 LLVMModuleRef module = ctx->module;
2606 BBInfo *bblocks = ctx->bblocks;
2608 LLVMValueRef personality;
2609 LLVMValueRef landing_pad;
2610 LLVMBasicBlockRef target_bb;
2612 static gint32 mapping_inited;
2613 static int ti_generator;
2616 LLVMValueRef type_info;
2620 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2622 if (cfg->compile_aot) {
2623 /* Use a dummy personality function */
2624 personality = LLVMGetNamedFunction (module, "mono_personality");
2625 g_assert (personality);
2627 personality = LLVMGetNamedFunction (module, "mono_personality");
2628 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2629 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2632 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2634 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2637 * Create the type info
2639 sprintf (ti_name, "type_info_%d", ti_generator);
2642 if (cfg->compile_aot) {
2643 /* decode_eh_frame () in aot-runtime.c will decode this */
2644 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2645 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2648 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2650 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2653 * After the cfg mempool is freed, the type info will point to stale memory,
2654 * but this is not a problem, since we decode it once in exception_cb during
2657 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2658 *(gint32*)ti = clause_index;
2660 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2662 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2666 LLVMTypeRef members [2], ret_type;
2668 members [0] = i8ptr;
2669 members [1] = LLVMInt32Type ();
2670 ret_type = LLVMStructType (members, 2, FALSE);
2672 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2673 LLVMAddClause (landing_pad, type_info);
2675 /* Store the exception into the exvar */
2677 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2681 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2682 * code expects control to be transferred to this landing pad even in the
2683 * presence of nested clauses. The landing pad needs to branch to the landing
2684 * pads belonging to nested clauses based on the selector value returned by
2685 * the landing pad instruction, which is passed to the landing pad in a
2686 * register by the EH code.
2688 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2689 g_assert (target_bb);
2692 * Branch to the correct landing pad
2694 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2695 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2697 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2698 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2699 MonoBasicBlock *handler_bb;
2701 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2702 g_assert (handler_bb);
2704 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2705 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2708 /* Start a new bblock which CALL_HANDLER can branch to */
2709 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2711 ctx->builder = builder = create_builder (ctx);
2712 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2714 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2716 /* Store the exception into the IL level exvar */
2717 if (bb->in_scount == 1) {
2718 g_assert (bb->in_scount == 1);
2719 exvar = bb->in_stack [0];
2721 // FIXME: This is shared with filter clauses ?
2722 g_assert (!values [exvar->dreg]);
2724 g_assert (ctx->ex_var);
2725 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2726 emit_volatile_store (ctx, exvar->dreg);
2732 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2734 MonoCompile *cfg = ctx->cfg;
2735 MonoMethodSignature *sig = ctx->sig;
2736 LLVMValueRef method = ctx->lmethod;
2737 LLVMValueRef *values = ctx->values;
2738 LLVMValueRef *addresses = ctx->addresses;
2739 LLVMCallInfo *linfo = ctx->linfo;
2740 LLVMModuleRef module = ctx->module;
2741 BBInfo *bblocks = ctx->bblocks;
2743 LLVMBasicBlockRef cbb;
2744 LLVMBuilderRef builder, starting_builder;
2745 gboolean has_terminator;
2747 LLVMValueRef lhs, rhs;
2750 cbb = get_bb (ctx, bb);
2751 builder = create_builder (ctx);
2752 ctx->builder = builder;
2753 LLVMPositionBuilderAtEnd (builder, cbb);
2755 if (bb == cfg->bb_entry)
2756 emit_entry_bb (ctx, builder);
2757 CHECK_FAILURE (ctx);
2759 if (bb->flags & BB_EXCEPTION_HANDLER) {
2760 if (!bblocks [bb->block_num].invoke_target) {
2761 LLVM_FAILURE (ctx, "handler without invokes");
2764 emit_handler_start (ctx, bb, builder);
2765 CHECK_FAILURE (ctx);
2766 builder = ctx->builder;
2769 has_terminator = FALSE;
2770 starting_builder = builder;
2771 for (ins = bb->code; ins; ins = ins->next) {
2772 const char *spec = LLVM_INS_INFO (ins->opcode);
2774 char dname_buf [128];
2776 emit_dbg_loc (ctx, builder, ins->cil_code);
2779 if (nins > 3000 && builder == starting_builder) {
2780 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2781 LLVM_FAILURE (ctx, "basic block too long");
2785 /* There could be instructions after a terminator, skip them */
2788 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2789 sprintf (dname_buf, "t%d", ins->dreg);
2793 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2794 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2796 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2797 lhs = emit_volatile_load (ctx, ins->sreg1);
2799 /* It is ok for SETRET to have an uninitialized argument */
2800 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2801 LLVM_FAILURE (ctx, "sreg1");
2802 lhs = values [ins->sreg1];
2808 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2809 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2810 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2811 rhs = emit_volatile_load (ctx, ins->sreg2);
2813 if (!values [ins->sreg2])
2814 LLVM_FAILURE (ctx, "sreg2");
2815 rhs = values [ins->sreg2];
2821 //mono_print_ins (ins);
2822 switch (ins->opcode) {
2825 case OP_LIVERANGE_START:
2826 case OP_LIVERANGE_END:
2829 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2832 #if SIZEOF_VOID_P == 4
2833 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2835 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2839 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2843 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2845 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2847 case OP_DUMMY_ICONST:
2848 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2850 case OP_DUMMY_I8CONST:
2851 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2853 case OP_DUMMY_R8CONST:
2854 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2857 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2858 has_terminator = TRUE;
2864 LLVMBasicBlockRef new_bb;
2865 LLVMBuilderRef new_builder;
2867 // The default branch is already handled
2868 // FIXME: Handle it here
2870 /* Start new bblock */
2871 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2872 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2874 lhs = convert (ctx, lhs, LLVMInt32Type ());
2875 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2876 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2877 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2879 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2882 new_builder = create_builder (ctx);
2883 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2884 LLVMBuildUnreachable (new_builder);
2886 has_terminator = TRUE;
2887 g_assert (!ins->next);
2893 switch (linfo->ret.storage) {
2894 case LLVMArgVtypeInReg: {
2895 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2896 LLVMValueRef part1, retval;
2899 size = get_vtype_size (sig->ret);
2901 g_assert (addresses [ins->sreg1]);
2903 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2904 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2906 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2908 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2910 LLVMBuildRet (builder, retval);
2913 case LLVMArgVtypeAsScalar: {
2914 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2915 LLVMValueRef retval;
2918 size = get_vtype_size (sig->ret);
2920 g_assert (addresses [ins->sreg1]);
2922 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
2923 LLVMBuildRet (builder, retval);
2926 case LLVMArgVtypeByVal: {
2927 LLVMValueRef retval;
2929 g_assert (addresses [ins->sreg1]);
2930 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2931 LLVMBuildRet (builder, retval);
2934 case LLVMArgVtypeByRef: {
2935 LLVMBuildRetVoid (builder);
2938 case LLVMArgVtypeRetAddr: {
2939 LLVMBuildRetVoid (builder);
2942 case LLVMArgFpStruct: {
2943 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2944 LLVMValueRef retval;
2946 g_assert (addresses [ins->sreg1]);
2947 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2948 LLVMBuildRet (builder, retval);
2952 if (!lhs || ctx->is_dead [ins->sreg1]) {
2954 * The method did not set its return value, probably because it
2955 * ends with a throw.
2958 LLVMBuildRetVoid (builder);
2960 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2962 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2964 has_terminator = TRUE;
2974 case OP_ICOMPARE_IMM:
2975 case OP_LCOMPARE_IMM:
2976 case OP_COMPARE_IMM: {
2980 if (ins->next->opcode == OP_NOP)
2983 if (ins->next->opcode == OP_BR)
2984 /* The comparison result is not needed */
2987 rel = mono_opcode_to_cond (ins->next->opcode);
2989 if (ins->opcode == OP_ICOMPARE_IMM) {
2990 lhs = convert (ctx, lhs, LLVMInt32Type ());
2991 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2993 if (ins->opcode == OP_LCOMPARE_IMM) {
2994 lhs = convert (ctx, lhs, LLVMInt64Type ());
2995 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2997 if (ins->opcode == OP_LCOMPARE) {
2998 lhs = convert (ctx, lhs, LLVMInt64Type ());
2999 rhs = convert (ctx, rhs, LLVMInt64Type ());
3001 if (ins->opcode == OP_ICOMPARE) {
3002 lhs = convert (ctx, lhs, LLVMInt32Type ());
3003 rhs = convert (ctx, rhs, LLVMInt32Type ());
3007 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3008 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
3009 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
3010 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
3013 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
3014 if (ins->opcode == OP_FCOMPARE) {
3015 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3016 } else if (ins->opcode == OP_RCOMPARE) {
3017 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3018 } else if (ins->opcode == OP_COMPARE_IMM) {
3019 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
3020 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
3022 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
3023 } else if (ins->opcode == OP_LCOMPARE_IMM) {
3024 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
3025 /* The immediate is encoded in two fields */
3026 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
3027 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
3029 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
3032 else if (ins->opcode == OP_COMPARE) {
3033 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
3034 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3036 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
3038 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3040 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
3041 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
3043 * If the target bb contains PHI instructions, LLVM requires
3044 * two PHI entries for this bblock, while we only generate one.
3045 * So convert this to an unconditional bblock. (bxc #171).
3047 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
3049 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
3051 has_terminator = TRUE;
3052 } else if (MONO_IS_SETCC (ins->next)) {
3053 sprintf (dname_buf, "t%d", ins->next->dreg);
3055 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3057 /* Add stores for volatile variables */
3058 emit_volatile_store (ctx, ins->next->dreg);
3059 } else if (MONO_IS_COND_EXC (ins->next)) {
3060 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
3061 CHECK_FAILURE (ctx);
3062 builder = ctx->builder;
3064 LLVM_FAILURE (ctx, "next");
3078 rel = mono_opcode_to_cond (ins->opcode);
3080 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3081 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3092 rel = mono_opcode_to_cond (ins->opcode);
3094 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3095 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3103 gboolean empty = TRUE;
3105 /* Check that all input bblocks really branch to us */
3106 for (i = 0; i < bb->in_count; ++i) {
3107 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3108 ins->inst_phi_args [i + 1] = -1;
3114 /* LLVM doesn't like phi instructions with zero operands */
3115 ctx->is_dead [ins->dreg] = TRUE;
3119 /* Created earlier, insert it now */
3120 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3122 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3123 int sreg1 = ins->inst_phi_args [i + 1];
3127 * Count the number of times the incoming bblock branches to us,
3128 * since llvm requires a separate entry for each.
3130 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3131 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3134 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3135 if (switch_ins->inst_many_bb [j] == bb)
3142 /* Remember for later */
3143 for (j = 0; j < count; ++j) {
3144 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3147 node->in_bb = bb->in_bb [i];
3149 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);
3159 values [ins->dreg] = lhs;
3163 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3166 values [ins->dreg] = lhs;
3168 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3170 * This is added by the spilling pass in case of the JIT,
3171 * but we have to do it ourselves.
3173 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3177 case OP_MOVE_F_TO_I4: {
3178 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3181 case OP_MOVE_I4_TO_F: {
3182 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3185 case OP_MOVE_F_TO_I8: {
3186 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3189 case OP_MOVE_I8_TO_F: {
3190 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3223 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3224 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3226 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3227 CHECK_FAILURE (ctx);
3228 builder = ctx->builder;
3230 switch (ins->opcode) {
3233 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3237 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3241 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3245 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3249 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3253 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3257 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3261 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3265 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3269 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3273 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3277 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3281 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3285 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3289 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3292 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3295 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3299 g_assert_not_reached ();
3306 lhs = convert (ctx, lhs, LLVMFloatType ());
3307 rhs = convert (ctx, rhs, LLVMFloatType ());
3308 switch (ins->opcode) {
3310 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3313 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3316 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3319 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3322 g_assert_not_reached ();
3331 case OP_IREM_UN_IMM:
3333 case OP_IDIV_UN_IMM:
3339 case OP_ISHR_UN_IMM:
3348 case OP_LSHR_UN_IMM:
3354 case OP_SHR_UN_IMM: {
3357 if (spec [MONO_INST_SRC1] == 'l') {
3358 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3360 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3363 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3364 CHECK_FAILURE (ctx);
3365 builder = ctx->builder;
3367 #if SIZEOF_VOID_P == 4
3368 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3369 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3372 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3373 lhs = convert (ctx, lhs, IntPtrType ());
3374 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3375 switch (ins->opcode) {
3379 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3383 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3387 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3391 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3393 case OP_IDIV_UN_IMM:
3394 case OP_LDIV_UN_IMM:
3395 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3399 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3401 case OP_IREM_UN_IMM:
3402 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3407 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3411 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3415 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3420 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3425 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3427 case OP_ISHR_UN_IMM:
3428 /* This is used to implement conv.u4, so the lhs could be an i8 */
3429 lhs = convert (ctx, lhs, LLVMInt32Type ());
3430 imm = convert (ctx, imm, LLVMInt32Type ());
3431 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3433 case OP_LSHR_UN_IMM:
3435 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3438 g_assert_not_reached ();
3443 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3446 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3449 lhs = convert (ctx, lhs, LLVMDoubleType ());
3450 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3453 lhs = convert (ctx, lhs, LLVMFloatType ());
3454 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3457 guint32 v = 0xffffffff;
3458 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3462 guint64 v = 0xffffffffffffffffLL;
3463 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3466 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3468 LLVMValueRef v1, v2;
3470 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3471 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3472 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3477 case OP_ICONV_TO_I1:
3478 case OP_ICONV_TO_I2:
3479 case OP_ICONV_TO_I4:
3480 case OP_ICONV_TO_U1:
3481 case OP_ICONV_TO_U2:
3482 case OP_ICONV_TO_U4:
3483 case OP_LCONV_TO_I1:
3484 case OP_LCONV_TO_I2:
3485 case OP_LCONV_TO_U1:
3486 case OP_LCONV_TO_U2:
3487 case OP_LCONV_TO_U4: {
3490 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);
3492 /* Have to do two casts since our vregs have type int */
3493 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3495 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3497 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3500 case OP_ICONV_TO_I8:
3501 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3503 case OP_ICONV_TO_U8:
3504 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3506 case OP_FCONV_TO_I4:
3507 case OP_RCONV_TO_I4:
3508 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3510 case OP_FCONV_TO_I1:
3511 case OP_RCONV_TO_I1:
3512 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3514 case OP_FCONV_TO_U1:
3515 case OP_RCONV_TO_U1:
3516 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3518 case OP_FCONV_TO_I2:
3519 case OP_RCONV_TO_I2:
3520 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3522 case OP_FCONV_TO_U2:
3523 case OP_RCONV_TO_U2:
3524 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3526 case OP_FCONV_TO_I8:
3527 case OP_RCONV_TO_I8:
3528 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3531 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3533 case OP_ICONV_TO_R8:
3534 case OP_LCONV_TO_R8:
3535 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3537 case OP_ICONV_TO_R_UN:
3538 case OP_LCONV_TO_R_UN:
3539 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3541 #if SIZEOF_VOID_P == 4
3544 case OP_LCONV_TO_I4:
3545 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3547 case OP_ICONV_TO_R4:
3548 case OP_LCONV_TO_R4:
3549 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3551 values [ins->dreg] = v;
3553 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3555 case OP_FCONV_TO_R4:
3556 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3558 values [ins->dreg] = v;
3560 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3562 case OP_RCONV_TO_R8:
3563 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3565 case OP_RCONV_TO_R4:
3566 values [ins->dreg] = lhs;
3569 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3572 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3575 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3577 case OP_LOCALLOC_IMM: {
3580 guint32 size = ins->inst_imm;
3581 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3583 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3585 if (ins->flags & MONO_INST_INIT) {
3586 LLVMValueRef args [5];
3589 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3590 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3591 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3592 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3593 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3596 values [ins->dreg] = v;
3600 LLVMValueRef v, size;
3602 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), "");
3604 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3606 if (ins->flags & MONO_INST_INIT) {
3607 LLVMValueRef args [5];
3610 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3612 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3613 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3614 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3616 values [ins->dreg] = v;
3620 case OP_LOADI1_MEMBASE:
3621 case OP_LOADU1_MEMBASE:
3622 case OP_LOADI2_MEMBASE:
3623 case OP_LOADU2_MEMBASE:
3624 case OP_LOADI4_MEMBASE:
3625 case OP_LOADU4_MEMBASE:
3626 case OP_LOADI8_MEMBASE:
3627 case OP_LOADR4_MEMBASE:
3628 case OP_LOADR8_MEMBASE:
3629 case OP_LOAD_MEMBASE:
3637 LLVMValueRef base, index, addr;
3639 gboolean sext = FALSE, zext = FALSE;
3640 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3642 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3647 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)) {
3648 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3653 if (ins->inst_offset == 0) {
3655 } else if (ins->inst_offset % size != 0) {
3656 /* Unaligned load */
3657 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3658 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3660 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3661 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3665 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3667 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3669 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3671 * These will signal LLVM that these loads do not alias any stores, and
3672 * they can't fail, allowing them to be hoisted out of loops.
3674 set_invariant_load_flag (values [ins->dreg]);
3675 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3679 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3681 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3682 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3683 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3687 case OP_STOREI1_MEMBASE_REG:
3688 case OP_STOREI2_MEMBASE_REG:
3689 case OP_STOREI4_MEMBASE_REG:
3690 case OP_STOREI8_MEMBASE_REG:
3691 case OP_STORER4_MEMBASE_REG:
3692 case OP_STORER8_MEMBASE_REG:
3693 case OP_STORE_MEMBASE_REG: {
3695 LLVMValueRef index, addr;
3697 gboolean sext = FALSE, zext = FALSE;
3698 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3700 if (!values [ins->inst_destbasereg])
3701 LLVM_FAILURE (ctx, "inst_destbasereg");
3703 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3705 if (ins->inst_offset % size != 0) {
3706 /* Unaligned store */
3707 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3708 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3710 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3711 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3713 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3717 case OP_STOREI1_MEMBASE_IMM:
3718 case OP_STOREI2_MEMBASE_IMM:
3719 case OP_STOREI4_MEMBASE_IMM:
3720 case OP_STOREI8_MEMBASE_IMM:
3721 case OP_STORE_MEMBASE_IMM: {
3723 LLVMValueRef index, addr;
3725 gboolean sext = FALSE, zext = FALSE;
3726 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3728 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3730 if (ins->inst_offset % size != 0) {
3731 /* Unaligned store */
3732 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3733 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3735 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3736 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3738 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3743 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3745 case OP_OUTARG_VTRETADDR:
3753 case OP_VOIDCALL_MEMBASE:
3754 case OP_CALL_MEMBASE:
3755 case OP_LCALL_MEMBASE:
3756 case OP_FCALL_MEMBASE:
3757 case OP_RCALL_MEMBASE:
3758 case OP_VCALL_MEMBASE:
3759 case OP_VOIDCALL_REG:
3764 case OP_VCALL_REG: {
3765 process_call (ctx, bb, &builder, ins);
3766 CHECK_FAILURE (ctx);
3771 LLVMValueRef indexes [2];
3773 LLVMValueRef got_entry_addr;
3776 * FIXME: Can't allocate from the cfg mempool since that is freed if
3777 * the LLVM compile fails.
3779 ji = g_new0 (MonoJumpInfo, 1);
3780 ji->type = (MonoJumpInfoType)ins->inst_i1;
3781 ji->data.target = ins->inst_p0;
3783 ji = mono_aot_patch_info_dup (ji);
3785 ji->next = cfg->patch_info;
3786 cfg->patch_info = ji;
3788 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3789 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3790 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3792 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3793 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3794 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3796 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3797 set_invariant_load_flag (values [ins->dreg]);
3800 case OP_NOT_REACHED:
3801 LLVMBuildUnreachable (builder);
3802 has_terminator = TRUE;
3803 g_assert (bb->block_num < cfg->max_block_num);
3804 ctx->unreachable [bb->block_num] = TRUE;
3805 /* Might have instructions after this */
3807 MonoInst *next = ins->next;
3809 * FIXME: If later code uses the regs defined by these instructions,
3810 * compilation will fail.
3812 MONO_DELETE_INS (bb, next);
3816 MonoInst *var = ins->inst_p0;
3818 if (var->opcode == OP_VTARG_ADDR) {
3819 /* The variable contains the vtype address */
3820 values [ins->dreg] = values [var->dreg];
3822 values [ins->dreg] = addresses [var->dreg];
3827 LLVMValueRef args [1];
3829 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3830 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3834 LLVMValueRef args [1];
3836 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3837 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3841 LLVMValueRef args [1];
3844 /* This no longer seems to happen */
3846 * LLVM optimizes sqrt(nan) into undefined in
3847 * lib/Analysis/ConstantFolding.cpp
3848 * Also, sqrt(NegativeInfinity) is optimized into 0.
3850 LLVM_FAILURE (ctx, "sqrt");
3852 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3853 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3857 LLVMValueRef args [1];
3859 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3860 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3874 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3875 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3877 switch (ins->opcode) {
3880 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3884 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3888 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3892 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3895 g_assert_not_reached ();
3898 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3901 case OP_ATOMIC_EXCHANGE_I4:
3902 case OP_ATOMIC_EXCHANGE_I8: {
3903 LLVMValueRef args [2];
3906 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3907 t = LLVMInt32Type ();
3909 t = LLVMInt64Type ();
3911 g_assert (ins->inst_offset == 0);
3913 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3914 args [1] = convert (ctx, rhs, t);
3916 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3919 case OP_ATOMIC_ADD_I4:
3920 case OP_ATOMIC_ADD_I8: {
3921 LLVMValueRef args [2];
3924 if (ins->opcode == OP_ATOMIC_ADD_I4)
3925 t = LLVMInt32Type ();
3927 t = LLVMInt64Type ();
3929 g_assert (ins->inst_offset == 0);
3931 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3932 args [1] = convert (ctx, rhs, t);
3933 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3936 case OP_ATOMIC_CAS_I4:
3937 case OP_ATOMIC_CAS_I8: {
3938 LLVMValueRef args [3], val;
3941 if (ins->opcode == OP_ATOMIC_CAS_I4)
3942 t = LLVMInt32Type ();
3944 t = LLVMInt64Type ();
3946 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3948 args [1] = convert (ctx, values [ins->sreg3], t);
3950 args [2] = convert (ctx, values [ins->sreg2], t);
3951 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3952 /* cmpxchg returns a pair */
3953 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3956 case OP_MEMORY_BARRIER: {
3957 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3960 case OP_ATOMIC_LOAD_I1:
3961 case OP_ATOMIC_LOAD_I2:
3962 case OP_ATOMIC_LOAD_I4:
3963 case OP_ATOMIC_LOAD_I8:
3964 case OP_ATOMIC_LOAD_U1:
3965 case OP_ATOMIC_LOAD_U2:
3966 case OP_ATOMIC_LOAD_U4:
3967 case OP_ATOMIC_LOAD_U8:
3968 case OP_ATOMIC_LOAD_R4:
3969 case OP_ATOMIC_LOAD_R8: {
3970 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3973 gboolean sext, zext;
3975 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3976 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3977 LLVMValueRef index, addr;
3979 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3984 if (ins->inst_offset != 0) {
3985 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3986 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3991 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3993 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3996 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3998 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4001 case OP_ATOMIC_STORE_I1:
4002 case OP_ATOMIC_STORE_I2:
4003 case OP_ATOMIC_STORE_I4:
4004 case OP_ATOMIC_STORE_I8:
4005 case OP_ATOMIC_STORE_U1:
4006 case OP_ATOMIC_STORE_U2:
4007 case OP_ATOMIC_STORE_U4:
4008 case OP_ATOMIC_STORE_U8:
4009 case OP_ATOMIC_STORE_R4:
4010 case OP_ATOMIC_STORE_R8: {
4011 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
4014 gboolean sext, zext;
4016 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4017 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
4018 LLVMValueRef index, addr, value;
4020 if (!values [ins->inst_destbasereg])
4021 LLVM_FAILURE (ctx, "inst_destbasereg");
4023 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4025 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4026 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4027 value = convert (ctx, values [ins->sreg1], t);
4029 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
4032 case OP_RELAXED_NOP: {
4033 #if defined(TARGET_AMD64) || defined(TARGET_X86)
4034 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
4041 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
4043 // 257 == FS segment register
4044 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
4046 // 256 == GS segment register
4047 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4050 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
4051 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
4052 /* See mono_amd64_emit_tls_get () */
4053 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
4055 // 256 == GS segment register
4056 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4057 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
4059 LLVM_FAILURE (ctx, "opcode tls-get");
4064 case OP_TLS_GET_REG: {
4065 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4066 /* See emit_tls_get_reg () */
4067 // 256 == GS segment register
4068 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4069 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
4071 LLVM_FAILURE (ctx, "opcode tls-get");
4080 case OP_IADD_OVF_UN:
4082 case OP_ISUB_OVF_UN:
4084 case OP_IMUL_OVF_UN:
4085 #if SIZEOF_VOID_P == 8
4087 case OP_LADD_OVF_UN:
4089 case OP_LSUB_OVF_UN:
4091 case OP_LMUL_OVF_UN:
4094 LLVMValueRef args [2], val, ovf, func;
4096 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4097 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4098 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4100 val = LLVMBuildCall (builder, func, args, 2, "");
4101 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4102 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4103 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4104 CHECK_FAILURE (ctx);
4105 builder = ctx->builder;
4111 * We currently model them using arrays. Promotion to local vregs is
4112 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4113 * so we always have an entry in cfg->varinfo for them.
4114 * FIXME: Is this needed ?
4117 MonoClass *klass = ins->klass;
4118 LLVMValueRef args [5];
4122 LLVM_FAILURE (ctx, "!klass");
4126 if (!addresses [ins->dreg])
4127 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4128 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4129 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4130 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4132 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4133 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4134 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4137 case OP_DUMMY_VZERO:
4140 case OP_STOREV_MEMBASE:
4141 case OP_LOADV_MEMBASE:
4143 MonoClass *klass = ins->klass;
4144 LLVMValueRef src = NULL, dst, args [5];
4145 gboolean done = FALSE;
4149 LLVM_FAILURE (ctx, "!klass");
4153 if (mini_is_gsharedvt_klass (klass)) {
4155 LLVM_FAILURE (ctx, "gsharedvt");
4159 switch (ins->opcode) {
4160 case OP_STOREV_MEMBASE:
4161 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4162 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4163 /* Decomposed earlier */
4164 g_assert_not_reached ();
4167 if (!addresses [ins->sreg1]) {
4169 g_assert (values [ins->sreg1]);
4170 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));
4171 LLVMBuildStore (builder, values [ins->sreg1], dst);
4174 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4175 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4178 case OP_LOADV_MEMBASE:
4179 if (!addresses [ins->dreg])
4180 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4181 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4182 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4185 if (!addresses [ins->sreg1])
4186 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4187 if (!addresses [ins->dreg])
4188 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4189 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4190 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4193 g_assert_not_reached ();
4195 CHECK_FAILURE (ctx);
4202 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4203 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4205 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4206 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4207 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4210 case OP_LLVM_OUTARG_VT:
4211 if (!addresses [ins->sreg1]) {
4212 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4213 g_assert (values [ins->sreg1]);
4214 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4216 addresses [ins->dreg] = addresses [ins->sreg1];
4222 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4224 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4227 case OP_LOADX_MEMBASE: {
4228 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4231 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4232 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4235 case OP_STOREX_MEMBASE: {
4236 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4239 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4240 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4247 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4251 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4257 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4261 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4265 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4269 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4272 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4275 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4278 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4282 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4293 LLVMValueRef v = NULL;
4295 switch (ins->opcode) {
4300 t = LLVMVectorType (LLVMInt32Type (), 4);
4301 rt = LLVMVectorType (LLVMFloatType (), 4);
4307 t = LLVMVectorType (LLVMInt64Type (), 2);
4308 rt = LLVMVectorType (LLVMDoubleType (), 2);
4311 t = LLVMInt32Type ();
4312 rt = LLVMInt32Type ();
4313 g_assert_not_reached ();
4316 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4317 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4318 switch (ins->opcode) {
4321 v = LLVMBuildAnd (builder, lhs, rhs, "");
4325 v = LLVMBuildOr (builder, lhs, rhs, "");
4329 v = LLVMBuildXor (builder, lhs, rhs, "");
4333 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4336 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4360 case OP_PADDB_SAT_UN:
4361 case OP_PADDW_SAT_UN:
4362 case OP_PSUBB_SAT_UN:
4363 case OP_PSUBW_SAT_UN:
4371 case OP_PMULW_HIGH_UN: {
4372 LLVMValueRef args [2];
4377 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4384 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4388 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4396 case OP_EXTRACTX_U2:
4398 case OP_EXTRACT_U1: {
4400 gboolean zext = FALSE;
4402 t = simd_op_to_llvm_type (ins->opcode);
4404 switch (ins->opcode) {
4412 case OP_EXTRACTX_U2:
4417 t = LLVMInt32Type ();
4418 g_assert_not_reached ();
4421 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4422 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4424 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4433 case OP_EXPAND_R8: {
4434 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4435 LLVMValueRef mask [16], v;
4438 for (i = 0; i < 16; ++i)
4439 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4441 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4443 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4444 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4449 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4452 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4455 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4458 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4461 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4464 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4475 case OP_EXTRACT_MASK:
4482 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4484 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4490 LLVMValueRef args [3];
4494 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4496 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4501 /* This is only used for implementing shifts by non-immediate */
4502 values [ins->dreg] = lhs;
4513 LLVMValueRef args [3];
4516 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4518 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4529 case OP_PSHLQ_REG: {
4530 LLVMValueRef args [3];
4533 args [1] = values [ins->sreg2];
4535 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4542 case OP_PSHUFLEW_LOW:
4543 case OP_PSHUFLEW_HIGH: {
4545 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4546 int i, mask_size = 0;
4547 int imask = ins->inst_c0;
4549 /* Convert the x86 shuffle mask to LLVM's */
4550 switch (ins->opcode) {
4553 mask [0] = ((imask >> 0) & 3);
4554 mask [1] = ((imask >> 2) & 3);
4555 mask [2] = ((imask >> 4) & 3) + 4;
4556 mask [3] = ((imask >> 6) & 3) + 4;
4557 v1 = values [ins->sreg1];
4558 v2 = values [ins->sreg2];
4562 mask [0] = ((imask >> 0) & 1);
4563 mask [1] = ((imask >> 1) & 1) + 2;
4564 v1 = values [ins->sreg1];
4565 v2 = values [ins->sreg2];
4567 case OP_PSHUFLEW_LOW:
4569 mask [0] = ((imask >> 0) & 3);
4570 mask [1] = ((imask >> 2) & 3);
4571 mask [2] = ((imask >> 4) & 3);
4572 mask [3] = ((imask >> 6) & 3);
4577 v1 = values [ins->sreg1];
4578 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4580 case OP_PSHUFLEW_HIGH:
4586 mask [4] = 4 + ((imask >> 0) & 3);
4587 mask [5] = 4 + ((imask >> 2) & 3);
4588 mask [6] = 4 + ((imask >> 4) & 3);
4589 mask [7] = 4 + ((imask >> 6) & 3);
4590 v1 = values [ins->sreg1];
4591 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4595 mask [0] = ((imask >> 0) & 3);
4596 mask [1] = ((imask >> 2) & 3);
4597 mask [2] = ((imask >> 4) & 3);
4598 mask [3] = ((imask >> 6) & 3);
4599 v1 = values [ins->sreg1];
4600 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4603 g_assert_not_reached ();
4605 for (i = 0; i < mask_size; ++i)
4606 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4608 values [ins->dreg] =
4609 LLVMBuildShuffleVector (builder, v1, v2,
4610 LLVMConstVector (mask_values, mask_size), dname);
4614 case OP_UNPACK_LOWB:
4615 case OP_UNPACK_LOWW:
4616 case OP_UNPACK_LOWD:
4617 case OP_UNPACK_LOWQ:
4618 case OP_UNPACK_LOWPS:
4619 case OP_UNPACK_LOWPD:
4620 case OP_UNPACK_HIGHB:
4621 case OP_UNPACK_HIGHW:
4622 case OP_UNPACK_HIGHD:
4623 case OP_UNPACK_HIGHQ:
4624 case OP_UNPACK_HIGHPS:
4625 case OP_UNPACK_HIGHPD: {
4627 LLVMValueRef mask_values [16];
4628 int i, mask_size = 0;
4629 gboolean low = FALSE;
4631 switch (ins->opcode) {
4632 case OP_UNPACK_LOWB:
4636 case OP_UNPACK_LOWW:
4640 case OP_UNPACK_LOWD:
4641 case OP_UNPACK_LOWPS:
4645 case OP_UNPACK_LOWQ:
4646 case OP_UNPACK_LOWPD:
4650 case OP_UNPACK_HIGHB:
4653 case OP_UNPACK_HIGHW:
4656 case OP_UNPACK_HIGHD:
4657 case OP_UNPACK_HIGHPS:
4660 case OP_UNPACK_HIGHQ:
4661 case OP_UNPACK_HIGHPD:
4665 g_assert_not_reached ();
4669 for (i = 0; i < (mask_size / 2); ++i) {
4671 mask [(i * 2) + 1] = mask_size + i;
4674 for (i = 0; i < (mask_size / 2); ++i) {
4675 mask [(i * 2)] = (mask_size / 2) + i;
4676 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4680 for (i = 0; i < mask_size; ++i)
4681 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4683 values [ins->dreg] =
4684 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4685 LLVMConstVector (mask_values, mask_size), dname);
4690 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4691 LLVMValueRef v, val;
4693 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4694 val = LLVMConstNull (t);
4695 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4696 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4698 values [ins->dreg] = val;
4702 case OP_DUPPS_HIGH: {
4703 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4704 LLVMValueRef v1, v2, val;
4707 if (ins->opcode == OP_DUPPS_LOW) {
4708 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4709 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4711 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4712 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4714 val = LLVMConstNull (t);
4715 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4716 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4717 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4718 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4720 values [ins->dreg] = val;
4728 case OP_GC_SAFE_POINT: {
4729 LLVMValueRef callee, cmp, val;
4730 LLVMTypeRef llvm_sig;
4731 const char *icall_name;
4732 LLVMBasicBlockRef poll_bb, cont_bb;
4734 poll_bb = gen_bb (ctx, "POLL_BB");
4735 cont_bb = gen_bb (ctx, "NOPOLL_BB");
4737 val = LLVMBuildLoad (ctx->builder, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type (), 0)), "");
4738 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstInt (LLVMTypeOf (val), 0, FALSE), "");
4739 LLVMBuildCondBr (ctx->builder, cmp, cont_bb, poll_bb);
4741 builder = ctx->builder = create_builder (ctx);
4742 LLVMPositionBuilderAtEnd (builder, poll_bb);
4744 MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
4745 sig->ret = &mono_get_void_class ()->byval_arg;
4746 icall_name = "mono_threads_state_poll";
4747 llvm_sig = sig_to_llvm_sig (ctx, sig);
4749 if (ctx->cfg->compile_aot) {
4750 callee = ctx->lmodule->state_poll;
4752 MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
4753 sig->ret = &mono_get_void_class ()->byval_arg;
4754 llvm_sig = sig_to_llvm_sig (ctx, sig);
4756 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4759 callee = ctx->lmodule->state_poll;
4761 MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
4762 sig->ret = &mono_get_void_class ()->byval_arg;
4763 llvm_sig = sig_to_llvm_sig (ctx, sig);
4765 callee = LLVMAddFunction (ctx->module, icall_name, llvm_sig);
4766 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4767 ctx->lmodule->state_poll = callee;
4771 // FIXME: This can use the PreserveAll cconv to avoid clobbering registers.
4772 // It requires the wrapper to also use that calling convention.
4774 val = emit_call (ctx, bb, &builder, callee, NULL, 0);
4775 LLVMBuildBr (builder, cont_bb);
4777 builder = ctx->builder = create_builder (ctx);
4778 LLVMPositionBuilderAtEnd (builder, cont_bb);
4780 bblocks [bb->block_num].end_bblock = cont_bb;
4785 * EXCEPTION HANDLING
4787 case OP_IMPLICIT_EXCEPTION:
4788 /* This marks a place where an implicit exception can happen */
4789 if (bb->region != -1)
4790 LLVM_FAILURE (ctx, "implicit-exception");
4794 MonoMethodSignature *throw_sig;
4795 LLVMValueRef callee, arg;
4796 gboolean rethrow = (ins->opcode == OP_RETHROW);
4797 const char *icall_name;
4799 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4800 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4803 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4804 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4805 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4806 if (cfg->compile_aot) {
4807 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4809 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4813 * LLVM doesn't push the exception argument, so we need a different
4816 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4818 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4822 mono_memory_barrier ();
4824 ctx->lmodule->rethrow = callee;
4826 ctx->lmodule->throw = callee;
4828 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4829 emit_call (ctx, bb, &builder, callee, &arg, 1);
4832 case OP_CALL_HANDLER: {
4834 * We don't 'call' handlers, but instead simply branch to them.
4835 * The code generated by ENDFINALLY will branch back to us.
4837 LLVMBasicBlockRef noex_bb;
4839 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4841 bb_list = info->call_handler_return_bbs;
4844 * Set the indicator variable for the finally clause.
4846 lhs = info->finally_ind;
4848 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4850 /* Branch to the finally clause */
4851 LLVMBuildBr (builder, info->call_handler_target_bb);
4853 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4854 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4856 builder = ctx->builder = create_builder (ctx);
4857 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4859 bblocks [bb->block_num].end_bblock = noex_bb;
4862 case OP_START_HANDLER: {
4865 case OP_ENDFINALLY: {
4866 LLVMBasicBlockRef resume_bb;
4867 MonoBasicBlock *handler_bb;
4868 LLVMValueRef val, switch_ins, callee;
4872 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4873 g_assert (handler_bb);
4874 info = &bblocks [handler_bb->block_num];
4875 lhs = info->finally_ind;
4878 bb_list = info->call_handler_return_bbs;
4880 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4882 /* Load the finally variable */
4883 val = LLVMBuildLoad (builder, lhs, "");
4885 /* Reset the variable */
4886 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4888 /* Branch to either resume_bb, or to the bblocks in bb_list */
4889 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4891 * The other targets are added at the end to handle OP_CALL_HANDLER
4892 * opcodes processed later.
4894 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4896 builder = ctx->builder = create_builder (ctx);
4897 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4899 if (ctx->cfg->compile_aot) {
4900 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4902 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4904 LLVMBuildCall (builder, callee, NULL, 0, "");
4906 LLVMBuildUnreachable (builder);
4907 has_terminator = TRUE;
4913 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4914 LLVM_FAILURE (ctx, reason);
4919 /* Convert the value to the type required by phi nodes */
4920 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4921 if (!values [ins->dreg])
4923 values [ins->dreg] = addresses [ins->dreg];
4925 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4928 /* Add stores for volatile variables */
4929 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4930 emit_volatile_store (ctx, ins->dreg);
4933 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4934 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4936 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4937 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4938 LLVMBuildRetVoid (builder);
4941 if (bb == cfg->bb_entry)
4942 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4951 * mono_llvm_check_method_supported:
4953 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4954 * compiling a method twice.
4957 mono_llvm_check_method_supported (MonoCompile *cfg)
4961 if (cfg->method->save_lmf) {
4962 cfg->exception_message = g_strdup ("lmf");
4963 cfg->disable_llvm = TRUE;
4965 if (cfg->disable_llvm)
4969 * Nested clauses where one of the clauses is a finally clause is
4970 * not supported, because LLVM can't figure out the control flow,
4971 * probably because we resume exception handling by calling our
4972 * own function instead of using the 'resume' llvm instruction.
4974 for (i = 0; i < cfg->header->num_clauses; ++i) {
4975 for (j = 0; j < cfg->header->num_clauses; ++j) {
4976 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4977 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4979 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4980 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4981 cfg->exception_message = g_strdup ("nested clauses");
4982 cfg->disable_llvm = TRUE;
4987 if (cfg->disable_llvm)
4991 if (cfg->method->dynamic) {
4992 cfg->exception_message = g_strdup ("dynamic.");
4993 cfg->disable_llvm = TRUE;
4995 if (cfg->disable_llvm)
5000 * mono_llvm_emit_method:
5002 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
5005 mono_llvm_emit_method (MonoCompile *cfg)
5008 MonoMethodSignature *sig;
5010 LLVMTypeRef method_type;
5011 LLVMValueRef method = NULL;
5013 LLVMValueRef *values;
5014 int i, max_block_num, bb_index;
5015 gboolean last = FALSE;
5016 GPtrArray *phi_values;
5017 LLVMCallInfo *linfo;
5019 LLVMModuleRef module;
5021 GPtrArray *bblock_list;
5022 MonoMethodHeader *header;
5023 MonoExceptionClause *clause;
5027 /* The code below might acquire the loader lock, so use it for global locking */
5028 mono_loader_lock ();
5030 /* Used to communicate with the callbacks */
5031 mono_native_tls_set_value (current_cfg_tls_id, cfg);
5033 ctx = g_new0 (EmitContext, 1);
5035 ctx->mempool = cfg->mempool;
5038 * This maps vregs to the LLVM instruction defining them
5040 values = g_new0 (LLVMValueRef, cfg->next_vreg);
5042 * This maps vregs for volatile variables to the LLVM instruction defining their
5045 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
5046 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
5047 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
5048 phi_values = g_ptr_array_sized_new (256);
5050 * This signals whenever the vreg was defined by a phi node with no input vars
5051 * (i.e. all its input bblocks end with NOT_REACHABLE).
5053 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
5054 /* Whenever the bblock is unreachable */
5055 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
5057 bblock_list = g_ptr_array_sized_new (256);
5059 ctx->values = values;
5060 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
5061 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
5063 if (cfg->compile_aot) {
5064 ctx->lmodule = &aot_module;
5065 method_name = mono_aot_get_method_name (cfg);
5066 cfg->llvm_method_name = g_strdup (method_name);
5068 init_jit_module (cfg->domain);
5069 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
5070 method_name = mono_method_full_name (cfg->method, TRUE);
5073 module = ctx->module = ctx->lmodule->module;
5076 LLVM_FAILURE (ctx, "gsharedvt");
5080 static int count = 0;
5083 if (g_getenv ("LLVM_COUNT")) {
5084 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
5085 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
5089 if (count > atoi (g_getenv ("LLVM_COUNT")))
5090 LLVM_FAILURE (ctx, "");
5095 sig = mono_method_signature (cfg->method);
5098 linfo = mono_arch_get_llvm_call_info (cfg, sig);
5100 CHECK_FAILURE (ctx);
5103 linfo->rgctx_arg = TRUE;
5104 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
5105 CHECK_FAILURE (ctx);
5108 * This maps parameter indexes in the original signature to the indexes in
5109 * the LLVM signature.
5111 ctx->pindexes = sinfo.pindexes;
5113 method = LLVMAddFunction (module, method_name, method_type);
5114 ctx->lmethod = method;
5116 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
5117 LLVMSetLinkage (method, LLVMPrivateLinkage);
5119 LLVMAddFunctionAttr (method, LLVMUWTable);
5121 if (cfg->compile_aot) {
5122 LLVMSetLinkage (method, LLVMInternalLinkage);
5123 if (ctx->lmodule->external_symbols) {
5124 LLVMSetLinkage (method, LLVMExternalLinkage);
5125 LLVMSetVisibility (method, LLVMHiddenVisibility);
5128 LLVMSetLinkage (method, LLVMPrivateLinkage);
5131 if (cfg->method->save_lmf)
5132 LLVM_FAILURE (ctx, "lmf");
5134 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
5135 LLVM_FAILURE (ctx, "pinvoke signature");
5137 header = cfg->header;
5138 for (i = 0; i < header->num_clauses; ++i) {
5139 clause = &header->clauses [i];
5140 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5141 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5143 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5144 /* We can't handle inlined methods with clauses */
5145 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5147 if (linfo->rgctx_arg) {
5148 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5150 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5151 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5152 * CC_X86_64_Mono in X86CallingConv.td.
5154 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5155 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5157 if (cfg->vret_addr) {
5158 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5159 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5160 if (linfo->ret.storage == LLVMArgVtypeByRef) {
5161 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMStructRetAttribute);
5162 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMNoAliasAttribute);
5166 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5167 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5170 names = g_new (char *, sig->param_count);
5171 mono_method_get_param_names (cfg->method, (const char **) names);
5173 for (i = 0; i < sig->param_count; ++i) {
5176 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5177 if (names [i] && names [i][0] != '\0')
5178 name = g_strdup_printf ("arg_%s", names [i]);
5180 name = g_strdup_printf ("arg_%d", i);
5181 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5183 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5184 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5186 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByRef) {
5188 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
5193 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5194 ctx->minfo = mono_debug_lookup_method (cfg->method);
5195 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5199 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5200 max_block_num = MAX (max_block_num, bb->block_num);
5201 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5203 /* Add branches between non-consecutive bblocks */
5204 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5205 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5206 bb->next_bb != bb->last_ins->inst_false_bb) {
5208 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5209 inst->opcode = OP_BR;
5210 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5211 mono_bblock_add_inst (bb, inst);
5216 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5217 * was later optimized away, so clear these flags, and add them back for the still
5218 * present OP_LDADDR instructions.
5220 for (i = 0; i < cfg->next_vreg; ++i) {
5223 ins = get_vreg_to_inst (cfg, i);
5224 if (ins && ins != cfg->rgctx_var)
5225 ins->flags &= ~MONO_INST_INDIRECT;
5229 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5231 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5233 LLVMBuilderRef builder;
5235 char dname_buf[128];
5237 builder = create_builder (ctx);
5239 for (ins = bb->code; ins; ins = ins->next) {
5240 switch (ins->opcode) {
5245 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5247 CHECK_FAILURE (ctx);
5249 if (ins->opcode == OP_VPHI) {
5250 /* Treat valuetype PHI nodes as operating on the address itself */
5251 g_assert (ins->klass);
5252 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5256 * Have to precreate these, as they can be referenced by
5257 * earlier instructions.
5259 sprintf (dname_buf, "t%d", ins->dreg);
5261 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5263 if (ins->opcode == OP_VPHI)
5264 ctx->addresses [ins->dreg] = values [ins->dreg];
5266 g_ptr_array_add (phi_values, values [ins->dreg]);
5269 * Set the expected type of the incoming arguments since these have
5270 * to have the same type.
5272 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5273 int sreg1 = ins->inst_phi_args [i + 1];
5276 ctx->vreg_types [sreg1] = phi_type;
5281 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5290 * Create an ordering for bblocks, use the depth first order first, then
5291 * put the exception handling bblocks last.
5293 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5294 bb = cfg->bblocks [bb_index];
5295 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5296 g_ptr_array_add (bblock_list, bb);
5297 bblocks [bb->block_num].added = TRUE;
5301 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5302 if (!bblocks [bb->block_num].added)
5303 g_ptr_array_add (bblock_list, bb);
5307 * Second pass: generate code.
5309 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5310 bb = g_ptr_array_index (bblock_list, bb_index);
5312 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5315 process_bb (ctx, bb);
5316 CHECK_FAILURE (ctx);
5319 /* Add incoming phi values */
5320 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5321 GSList *l, *ins_list;
5323 ins_list = bblocks [bb->block_num].phi_nodes;
5325 for (l = ins_list; l; l = l->next) {
5326 PhiNode *node = l->data;
5327 MonoInst *phi = node->phi;
5328 int sreg1 = node->sreg;
5329 LLVMBasicBlockRef in_bb;
5334 in_bb = get_end_bb (ctx, node->in_bb);
5336 if (ctx->unreachable [node->in_bb->block_num])
5339 if (!values [sreg1])
5340 /* Can happen with values in EH clauses */
5341 LLVM_FAILURE (ctx, "incoming phi sreg1");
5343 if (phi->opcode == OP_VPHI) {
5344 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5345 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5347 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5349 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5350 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5351 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5356 /* Create the SWITCH statements for ENDFINALLY instructions */
5357 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5358 BBInfo *info = &bblocks [bb->block_num];
5360 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5361 LLVMValueRef switch_ins = l->data;
5362 GSList *bb_list = info->call_handler_return_bbs;
5364 for (i = 0; i < g_slist_length (bb_list); ++i)
5365 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5369 if (cfg->verbose_level > 1)
5370 mono_llvm_dump_value (method);
5372 if (cfg->compile_aot)
5373 mark_as_used (ctx->lmodule, method);
5375 if (cfg->compile_aot) {
5376 LLVMValueRef md_args [16];
5377 LLVMValueRef md_node;
5380 method_index = mono_aot_get_method_index (cfg->orig_method);
5381 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5382 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5383 md_node = LLVMMDNode (md_args, 2);
5384 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5385 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5388 if (cfg->compile_aot) {
5389 /* Don't generate native code, keep the LLVM IR */
5390 if (cfg->compile_aot && cfg->verbose_level)
5391 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5393 //LLVMVerifyFunction(method, 0);
5395 //LLVMVerifyFunction(method, 0);
5396 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5398 if (cfg->verbose_level > 1)
5399 mono_llvm_dump_value (method);
5401 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5403 /* Set by emit_cb */
5404 g_assert (cfg->code_len);
5406 /* FIXME: Free the LLVM IL for the function */
5409 if (ctx->lmodule->method_to_lmethod)
5410 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5417 /* Need to add unused phi nodes as they can be referenced by other values */
5418 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5419 LLVMBuilderRef builder;
5421 builder = create_builder (ctx);
5422 LLVMPositionBuilderAtEnd (builder, phi_bb);
5424 for (i = 0; i < phi_values->len; ++i) {
5425 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5426 if (LLVMGetInstructionParent (v) == NULL)
5427 LLVMInsertIntoBuilder (builder, v);
5430 LLVMDeleteFunction (method);
5435 g_free (ctx->addresses);
5436 g_free (ctx->vreg_types);
5437 g_free (ctx->vreg_cli_types);
5438 g_free (ctx->pindexes);
5439 g_free (ctx->is_dead);
5440 g_free (ctx->unreachable);
5441 g_ptr_array_free (phi_values, TRUE);
5442 g_free (ctx->bblocks);
5443 g_hash_table_destroy (ctx->region_to_handler);
5444 g_hash_table_destroy (ctx->clause_to_handler);
5445 g_free (method_name);
5446 g_ptr_array_free (bblock_list, TRUE);
5448 for (l = ctx->builders; l; l = l->next) {
5449 LLVMBuilderRef builder = l->data;
5450 LLVMDisposeBuilder (builder);
5455 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5457 mono_loader_unlock ();
5461 * mono_llvm_emit_call:
5463 * Same as mono_arch_emit_call () for LLVM.
5466 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5469 MonoMethodSignature *sig;
5470 int i, n, stack_size;
5475 sig = call->signature;
5476 n = sig->param_count + sig->hasthis;
5478 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5480 if (cfg->disable_llvm)
5483 if (sig->call_convention == MONO_CALL_VARARG) {
5484 cfg->exception_message = g_strdup ("varargs");
5485 cfg->disable_llvm = TRUE;
5488 for (i = 0; i < n; ++i) {
5491 ainfo = call->cinfo->args + i;
5493 in = call->args [i];
5495 /* Simply remember the arguments */
5496 switch (ainfo->storage) {
5498 case LLVMArgInFPReg: {
5499 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5502 opcode = mono_type_to_regmove (cfg, t);
5503 if (opcode == OP_FMOVE) {
5504 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5505 ins->dreg = mono_alloc_freg (cfg);
5506 } else if (opcode == OP_LMOVE) {
5507 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5508 ins->dreg = mono_alloc_lreg (cfg);
5510 MONO_INST_NEW (cfg, ins, OP_MOVE);
5511 ins->dreg = mono_alloc_ireg (cfg);
5513 ins->sreg1 = in->dreg;
5516 case LLVMArgVtypeByVal:
5517 case LLVMArgVtypeByRef:
5518 case LLVMArgVtypeInReg:
5519 case LLVMArgVtypeAsScalar:
5520 case LLVMArgAsIArgs:
5521 case LLVMArgAsFpArgs:
5522 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5523 ins->dreg = mono_alloc_ireg (cfg);
5524 ins->sreg1 = in->dreg;
5525 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5528 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5529 cfg->exception_message = g_strdup ("ainfo->storage");
5530 cfg->disable_llvm = TRUE;
5534 if (!cfg->disable_llvm) {
5535 MONO_ADD_INS (cfg->cbb, ins);
5536 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5541 static unsigned char*
5542 alloc_cb (LLVMValueRef function, int size)
5546 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5550 return mono_domain_code_reserve (cfg->domain, size);
5552 return mono_domain_code_reserve (mono_domain_get (), size);
5557 emitted_cb (LLVMValueRef function, void *start, void *end)
5561 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5563 cfg->code_len = (guint8*)end - (guint8*)start;
5567 exception_cb (void *data)
5570 MonoJitExceptionInfo *ei;
5571 guint32 ei_len, i, j, nested_len, nindex;
5572 gpointer *type_info;
5573 int this_reg, this_offset;
5575 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5579 * data points to a DWARF FDE structure, convert it to our unwind format and
5581 * An alternative would be to save it directly, and modify our unwinder to work
5584 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);
5585 if (cfg->verbose_level > 1)
5586 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5588 /* Count nested clauses */
5590 for (i = 0; i < ei_len; ++i) {
5591 gint32 cindex1 = *(gint32*)type_info [i];
5592 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5594 for (j = 0; j < cfg->header->num_clauses; ++j) {
5596 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5598 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5604 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5605 cfg->llvm_ex_info_len = ei_len + nested_len;
5606 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5607 /* Fill the rest of the information from the type info */
5608 for (i = 0; i < ei_len; ++i) {
5609 gint32 clause_index = *(gint32*)type_info [i];
5610 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5612 cfg->llvm_ex_info [i].flags = clause->flags;
5613 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5614 cfg->llvm_ex_info [i].clause_index = clause_index;
5618 * For nested clauses, the LLVM produced exception info associates the try interval with
5619 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5620 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5621 * and everything else from the nested clause.
5624 for (i = 0; i < ei_len; ++i) {
5625 gint32 cindex1 = *(gint32*)type_info [i];
5626 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5628 for (j = 0; j < cfg->header->num_clauses; ++j) {
5630 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5631 MonoJitExceptionInfo *nesting_ei, *nested_ei;
5633 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5634 /* clause1 is the nested clause */
5635 nested_ei = &cfg->llvm_ex_info [i];
5636 nesting_ei = &cfg->llvm_ex_info [nindex];
5639 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
5641 nesting_ei->flags = clause2->flags;
5642 nesting_ei->data.catch_class = clause2->data.catch_class;
5643 nesting_ei->clause_index = cindex2;
5647 g_assert (nindex == ei_len + nested_len);
5648 cfg->llvm_this_reg = this_reg;
5649 cfg->llvm_this_offset = this_offset;
5651 /* type_info [i] is cfg mempool allocated, no need to free it */
5658 dlsym_cb (const char *name, void **symbol)
5664 if (!strcmp (name, "__bzero")) {
5665 *symbol = (void*)bzero;
5667 current = mono_dl_open (NULL, 0, NULL);
5670 err = mono_dl_symbol (current, name, symbol);
5672 mono_dl_close (current);
5674 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5675 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5681 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5683 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5687 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5689 LLVMTypeRef param_types [4];
5691 param_types [0] = param_type1;
5692 param_types [1] = param_type2;
5694 AddFunc (module, name, ret_type, param_types, 2);
5698 add_intrinsics (LLVMModuleRef module)
5700 /* Emit declarations of instrinsics */
5702 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5703 * type doesn't seem to do any locking.
5706 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5708 memset_param_count = 5;
5709 memset_func_name = "llvm.memset.p0i8.i32";
5711 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5715 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5717 memcpy_param_count = 5;
5718 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5720 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5724 LLVMTypeRef params [] = { LLVMDoubleType () };
5726 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5727 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5728 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5730 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5731 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5735 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5736 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5737 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5739 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5740 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5741 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5742 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5743 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5744 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5745 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5749 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5750 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5751 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5753 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5754 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5755 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5756 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5757 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5758 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5763 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5765 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5768 /* SSE intrinsics */
5769 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5771 LLVMTypeRef ret_type, arg_types [16];
5774 ret_type = type_to_simd_type (MONO_TYPE_I4);
5775 arg_types [0] = ret_type;
5776 arg_types [1] = ret_type;
5777 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5778 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5780 ret_type = type_to_simd_type (MONO_TYPE_I2);
5781 arg_types [0] = ret_type;
5782 arg_types [1] = ret_type;
5783 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5784 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5785 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5786 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5787 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5788 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5789 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5790 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5791 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5792 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5794 ret_type = type_to_simd_type (MONO_TYPE_I1);
5795 arg_types [0] = ret_type;
5796 arg_types [1] = ret_type;
5797 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5798 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5799 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5800 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5801 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5802 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5803 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5805 ret_type = type_to_simd_type (MONO_TYPE_R8);
5806 arg_types [0] = ret_type;
5807 arg_types [1] = ret_type;
5808 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5809 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5810 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5811 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5812 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5814 ret_type = type_to_simd_type (MONO_TYPE_R4);
5815 arg_types [0] = ret_type;
5816 arg_types [1] = ret_type;
5817 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5818 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5819 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5820 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5821 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5824 ret_type = type_to_simd_type (MONO_TYPE_I1);
5825 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5826 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5827 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5828 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5829 ret_type = type_to_simd_type (MONO_TYPE_I2);
5830 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5831 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5832 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5833 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5836 ret_type = type_to_simd_type (MONO_TYPE_R8);
5837 arg_types [0] = ret_type;
5838 arg_types [1] = ret_type;
5839 arg_types [2] = LLVMInt8Type ();
5840 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5841 ret_type = type_to_simd_type (MONO_TYPE_R4);
5842 arg_types [0] = ret_type;
5843 arg_types [1] = ret_type;
5844 arg_types [2] = LLVMInt8Type ();
5845 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5847 /* Conversion ops */
5848 ret_type = type_to_simd_type (MONO_TYPE_R8);
5849 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5850 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5851 ret_type = type_to_simd_type (MONO_TYPE_R4);
5852 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5853 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5854 ret_type = type_to_simd_type (MONO_TYPE_I4);
5855 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5856 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5857 ret_type = type_to_simd_type (MONO_TYPE_I4);
5858 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5859 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5860 ret_type = type_to_simd_type (MONO_TYPE_R4);
5861 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5862 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5863 ret_type = type_to_simd_type (MONO_TYPE_R8);
5864 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5865 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5867 ret_type = type_to_simd_type (MONO_TYPE_I4);
5868 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5869 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5870 ret_type = type_to_simd_type (MONO_TYPE_I4);
5871 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5872 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5875 ret_type = type_to_simd_type (MONO_TYPE_R8);
5876 arg_types [0] = ret_type;
5877 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5878 ret_type = type_to_simd_type (MONO_TYPE_R4);
5879 arg_types [0] = ret_type;
5880 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5881 ret_type = type_to_simd_type (MONO_TYPE_R4);
5882 arg_types [0] = ret_type;
5883 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5884 ret_type = type_to_simd_type (MONO_TYPE_R4);
5885 arg_types [0] = ret_type;
5886 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5889 ret_type = type_to_simd_type (MONO_TYPE_I2);
5890 arg_types [0] = ret_type;
5891 arg_types [1] = LLVMInt32Type ();
5892 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5893 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5894 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5895 ret_type = type_to_simd_type (MONO_TYPE_I4);
5896 arg_types [0] = ret_type;
5897 arg_types [1] = LLVMInt32Type ();
5898 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5899 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5900 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5901 ret_type = type_to_simd_type (MONO_TYPE_I8);
5902 arg_types [0] = ret_type;
5903 arg_types [1] = LLVMInt32Type ();
5904 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5905 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5908 ret_type = LLVMInt32Type ();
5909 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5910 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5913 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5916 /* Load/Store intrinsics */
5918 LLVMTypeRef arg_types [5];
5922 for (i = 1; i <= 8; i *= 2) {
5923 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5924 arg_types [1] = LLVMInt32Type ();
5925 arg_types [2] = LLVMInt1Type ();
5926 arg_types [3] = LLVMInt32Type ();
5927 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5928 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5930 arg_types [0] = LLVMIntType (i * 8);
5931 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5932 arg_types [2] = LLVMInt32Type ();
5933 arg_types [3] = LLVMInt1Type ();
5934 arg_types [4] = LLVMInt32Type ();
5935 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5936 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5942 add_types (MonoLLVMModule *lmodule)
5944 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5948 mono_llvm_init (void)
5950 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5954 init_jit_module (MonoDomain *domain)
5956 MonoJitICallInfo *info;
5957 MonoJitDomainInfo *dinfo;
5958 MonoLLVMModule *module;
5961 dinfo = domain_jit_info (domain);
5962 if (dinfo->llvm_module)
5965 mono_loader_lock ();
5967 if (dinfo->llvm_module) {
5968 mono_loader_unlock ();
5972 module = g_new0 (MonoLLVMModule, 1);
5974 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5975 module->module = LLVMModuleCreateWithName (name);
5977 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5979 add_intrinsics (module->module);
5982 module->llvm_types = g_hash_table_new (NULL, NULL);
5984 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5986 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5988 mono_memory_barrier ();
5990 dinfo->llvm_module = module;
5992 mono_loader_unlock ();
5996 mono_llvm_cleanup (void)
5998 if (aot_module.module)
5999 LLVMDisposeModule (aot_module.module);
6001 LLVMContextDispose (LLVMGetGlobalContext ());
6005 mono_llvm_free_domain_info (MonoDomain *domain)
6007 MonoJitDomainInfo *info = domain_jit_info (domain);
6008 MonoLLVMModule *module = info->llvm_module;
6014 if (module->llvm_types)
6015 g_hash_table_destroy (module->llvm_types);
6017 mono_llvm_dispose_ee (module->mono_ee);
6019 if (module->bb_names) {
6020 for (i = 0; i < module->bb_names_len; ++i)
6021 g_free (module->bb_names [i]);
6022 g_free (module->bb_names);
6024 //LLVMDisposeModule (module->module);
6028 info->llvm_module = NULL;
6032 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link)
6034 MonoLLVMModule *lmodule = &aot_module;
6036 /* Delete previous module */
6037 if (lmodule->plt_entries)
6038 g_hash_table_destroy (lmodule->plt_entries);
6039 if (lmodule->module)
6040 LLVMDisposeModule (lmodule->module);
6042 memset (lmodule, 0, sizeof (aot_module));
6044 lmodule->module = LLVMModuleCreateWithName ("aot");
6045 lmodule->assembly = assembly;
6046 lmodule->global_prefix = g_strdup (global_prefix);
6047 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
6048 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
6049 lmodule->external_symbols = TRUE;
6050 lmodule->emit_dwarf = emit_dwarf;
6051 lmodule->static_link = static_link;
6052 /* The first few entries are reserved */
6053 lmodule->max_got_offset = 16;
6055 add_intrinsics (lmodule->module);
6056 add_types (lmodule);
6060 * We couldn't compute the type of the LLVM global representing the got because
6061 * its size is only known after all the methods have been emitted. So create
6062 * a dummy variable, and replace all uses it with the real got variable when
6063 * its size is known in mono_llvm_emit_aot_module ().
6066 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
6068 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
6069 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
6072 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
6073 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
6074 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
6075 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
6079 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
6082 LLVMValueRef res, *vals;
6084 vals = g_new0 (LLVMValueRef, nvalues);
6085 for (i = 0; i < nvalues; ++i)
6086 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
6087 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
6093 * mono_llvm_emit_aot_file_info:
6095 * Emit the MonoAotFileInfo structure.
6096 * Same as emit_aot_file_info () in aot-compiler.c.
6099 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
6101 MonoLLVMModule *lmodule = &aot_module;
6103 /* Save these for later */
6104 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
6105 lmodule->has_jitted_code = has_jitted_code;
6109 * mono_llvm_emit_aot_data:
6111 * Emit the binary data DATA pointed to by symbol SYMBOL.
6114 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
6116 MonoLLVMModule *lmodule = &aot_module;
6120 type = LLVMArrayType (LLVMInt8Type (), data_len);
6121 d = LLVMAddGlobal (lmodule->module, type, symbol);
6122 LLVMSetVisibility (d, LLVMHiddenVisibility);
6123 LLVMSetLinkage (d, LLVMInternalLinkage);
6124 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
6125 mono_llvm_set_is_constant (d);
6128 /* Add a reference to a global defined in JITted code */
6130 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
6135 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
6136 v = LLVMAddGlobal (lmodule->module, LLVMInt8Type (), s);
6142 emit_aot_file_info (MonoLLVMModule *lmodule)
6144 LLVMTypeRef file_info_type;
6145 LLVMTypeRef *eltypes, eltype;
6146 LLVMValueRef info_var;
6147 LLVMValueRef *fields;
6148 int i, nfields, tindex;
6149 MonoAotFileInfo *info;
6151 info = &lmodule->aot_info;
6153 /* Create an LLVM type to represent MonoAotFileInfo */
6155 eltypes = g_new (LLVMTypeRef, nfields);
6157 eltypes [tindex ++] = LLVMInt32Type ();
6158 eltypes [tindex ++] = LLVMInt32Type ();
6160 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6161 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
6163 for (i = 0; i < 13; ++i)
6164 eltypes [tindex ++] = LLVMInt32Type ();
6166 for (i = 0; i < 4; ++i)
6167 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6168 g_assert (tindex == nfields);
6169 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6170 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6172 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
6173 if (lmodule->static_link) {
6174 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
6175 LLVMSetLinkage (info_var, LLVMInternalLinkage);
6177 fields = g_new (LLVMValueRef, nfields);
6179 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6180 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6184 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6185 * for symbols defined in the .s file emitted by the aot compiler.
6187 eltype = eltypes [tindex];
6188 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
6189 fields [tindex ++] = lmodule->got_var;
6190 /* llc defines this directly */
6191 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
6192 if (TRUE || lmodule->has_jitted_code) {
6193 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
6194 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
6195 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
6197 fields [tindex ++] = LLVMConstNull (eltype);
6198 fields [tindex ++] = LLVMConstNull (eltype);
6199 fields [tindex ++] = LLVMConstNull (eltype);
6201 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
6202 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
6203 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
6204 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
6205 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
6206 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
6207 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
6208 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
6209 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
6210 /* Not needed (mem_end) */
6211 fields [tindex ++] = LLVMConstNull (eltype);
6212 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
6213 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
6214 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
6215 if (info->trampoline_size [0]) {
6216 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
6217 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
6218 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
6219 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
6221 fields [tindex ++] = LLVMConstNull (eltype);
6222 fields [tindex ++] = LLVMConstNull (eltype);
6223 fields [tindex ++] = LLVMConstNull (eltype);
6224 fields [tindex ++] = LLVMConstNull (eltype);
6226 if (lmodule->static_link)
6227 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
6229 fields [tindex ++] = LLVMConstNull (eltype);
6230 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
6231 if (TRUE || lmodule->has_jitted_code) {
6232 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
6233 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
6234 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
6235 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
6236 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
6237 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
6239 fields [tindex ++] = LLVMConstNull (eltype);
6240 fields [tindex ++] = LLVMConstNull (eltype);
6241 fields [tindex ++] = LLVMConstNull (eltype);
6242 fields [tindex ++] = LLVMConstNull (eltype);
6243 fields [tindex ++] = LLVMConstNull (eltype);
6244 fields [tindex ++] = LLVMConstNull (eltype);
6247 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6248 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
6251 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6252 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6253 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6254 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6255 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6256 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6257 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6258 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6259 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6260 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6261 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6262 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6263 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6265 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6266 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6267 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6268 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6269 g_assert (tindex == nfields);
6271 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6273 if (lmodule->static_link) {
6277 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
6278 /* Get rid of characters which cannot occur in symbols */
6280 for (p = s; *p; ++p) {
6281 if (!(isalnum (*p) || *p == '_'))
6284 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
6286 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
6287 LLVMSetLinkage (var, LLVMExternalLinkage);
6292 * Emit the aot module into the LLVM bitcode file FILENAME.
6295 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6297 LLVMTypeRef got_type;
6298 LLVMValueRef real_got;
6299 MonoLLVMModule *module = &aot_module;
6302 * Create the real got variable and replace all uses of the dummy variable with
6305 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6306 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6307 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6308 if (module->external_symbols) {
6309 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6310 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6312 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6314 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6316 mark_as_used (&aot_module, real_got);
6318 /* Delete the dummy got so it doesn't become a global */
6319 LLVMDeleteGlobal (aot_module.got_var);
6320 aot_module.got_var = real_got;
6322 emit_llvm_used (&aot_module);
6323 emit_dbg_info (&aot_module, filename, cu_name);
6324 emit_aot_file_info (&aot_module);
6326 /* Replace PLT entries for directly callable methods with the methods themselves */
6328 GHashTableIter iter;
6330 LLVMValueRef callee;
6332 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6333 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6334 if (mono_aot_is_direct_callable (ji)) {
6335 LLVMValueRef lmethod;
6337 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6338 /* The types might not match because the caller might pass an rgctx */
6339 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6340 mono_llvm_replace_uses_of (callee, lmethod);
6341 mono_aot_mark_unused_llvm_plt_entry (ji);
6351 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6352 g_assert_not_reached ();
6357 LLVMWriteBitcodeToFile (aot_module.module, filename);
6362 md_string (const char *s)
6364 return LLVMMDString (s, strlen (s));
6367 /* Debugging support */
6370 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6372 LLVMModuleRef module = lmodule->module;
6373 LLVMValueRef args [16], cu_args [16], cu, ver;
6375 char *build_info, *s, *dir;
6378 * This can only be enabled when LLVM code is emitted into a separate object
6379 * file, since the AOT compiler also emits dwarf info,
6380 * and the abbrev indexes will not be correct since llvm has added its own
6383 if (!lmodule->emit_dwarf)
6387 * Emit dwarf info in the form of LLVM metadata. There is some
6388 * out-of-date documentation at:
6389 * http://llvm.org/docs/SourceLevelDebugging.html
6390 * but most of this was gathered from the llvm and
6395 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6396 /* CU name/compilation dir */
6397 dir = g_path_get_dirname (filename);
6398 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6399 args [1] = LLVMMDString (dir, strlen (dir));
6400 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6403 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6405 build_info = mono_get_runtime_build_info ();
6406 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6407 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6408 g_free (build_info);
6410 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6412 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6413 /* Runtime version */
6414 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6416 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6417 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6419 if (lmodule->subprogram_mds) {
6423 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6424 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6425 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6426 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6428 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6431 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6432 /* Imported modules */
6433 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6435 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6436 /* DebugEmissionKind = FullDebug */
6437 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6438 cu = LLVMMDNode (cu_args, n_cuargs);
6439 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6441 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6442 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6443 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6444 ver = LLVMMDNode (args, 3);
6445 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6447 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6448 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6449 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6450 ver = LLVMMDNode (args, 3);
6451 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6455 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6457 MonoLLVMModule *module = ctx->lmodule;
6458 MonoDebugMethodInfo *minfo = ctx->minfo;
6459 char *source_file, *dir, *filename;
6460 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6461 MonoSymSeqPoint *sym_seq_points;
6467 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6469 source_file = g_strdup ("<unknown>");
6470 dir = g_path_get_dirname (source_file);
6471 filename = g_path_get_basename (source_file);
6473 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6474 args [0] = md_string (filename);
6475 args [1] = md_string (dir);
6476 ctx_args [1] = LLVMMDNode (args, 2);
6477 ctx_md = LLVMMDNode (ctx_args, 2);
6479 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6480 type_args [1] = NULL;
6481 type_args [2] = NULL;
6482 type_args [3] = LLVMMDString ("", 0);
6483 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6484 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6485 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6486 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6487 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6488 type_args [9] = NULL;
6489 type_args [10] = NULL;
6490 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6491 type_args [12] = NULL;
6492 type_args [13] = NULL;
6493 type_args [14] = NULL;
6494 type_md = LLVMMDNode (type_args, 14);
6496 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6497 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6498 /* Source directory + file pair */
6499 args [0] = md_string (filename);
6500 args [1] = md_string (dir);
6501 md_args [1] = LLVMMDNode (args ,2);
6502 md_args [2] = ctx_md;
6503 md_args [3] = md_string (cfg->method->name);
6504 md_args [4] = md_string (name);
6505 md_args [5] = md_string (name);
6508 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6510 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6512 md_args [7] = type_md;
6514 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6516 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6518 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6519 /* Index into a virtual function */
6520 md_args [11] = NULL;
6521 md_args [12] = NULL;
6523 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6525 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6526 /* Pointer to LLVM function */
6527 md_args [15] = method;
6528 /* Function template parameter */
6529 md_args [16] = NULL;
6530 /* Function declaration descriptor */
6531 md_args [17] = NULL;
6532 /* List of function variables */
6533 md_args [18] = LLVMMDNode (args, 0);
6535 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6536 md = LLVMMDNode (md_args, 20);
6538 if (!module->subprogram_mds)
6539 module->subprogram_mds = g_ptr_array_new ();
6540 g_ptr_array_add (module->subprogram_mds, md);
6544 g_free (source_file);
6545 g_free (sym_seq_points);
6551 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6553 MonoCompile *cfg = ctx->cfg;
6555 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6556 MonoDebugSourceLocation *loc;
6557 LLVMValueRef loc_md, md_args [16];
6560 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6564 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6565 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6566 md_args [nmd_args ++] = ctx->dbg_md;
6567 md_args [nmd_args ++] = NULL;
6568 loc_md = LLVMMDNode (md_args, nmd_args);
6569 LLVMSetCurrentDebugLocation (builder, loc_md);
6570 mono_debug_symfile_free_location (loc);
6577 - Emit LLVM IR from the mono IR using the LLVM C API.
6578 - The original arch specific code remains, so we can fall back to it if we run
6579 into something we can't handle.
6583 A partial list of issues:
6584 - Handling of opcodes which can throw exceptions.
6586 In the mono JIT, these are implemented using code like this:
6593 push throw_pos - method
6594 call <exception trampoline>
6596 The problematic part is push throw_pos - method, which cannot be represented
6597 in the LLVM IR, since it does not support label values.
6598 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6599 be implemented in JIT mode ?
6600 -> a possible but slower implementation would use the normal exception
6601 throwing code but it would need to control the placement of the throw code
6602 (it needs to be exactly after the compare+branch).
6603 -> perhaps add a PC offset intrinsics ?
6605 - efficient implementation of .ovf opcodes.
6607 These are currently implemented as:
6608 <ins which sets the condition codes>
6611 Some overflow opcodes are now supported by LLVM SVN.
6613 - exception handling, unwinding.
6614 - SSA is disabled for methods with exception handlers
6615 - How to obtain unwind info for LLVM compiled methods ?
6616 -> this is now solved by converting the unwind info generated by LLVM
6618 - LLVM uses the c++ exception handling framework, while we use our home grown
6619 code, and couldn't use the c++ one:
6620 - its not supported under VC++, other exotic platforms.
6621 - it might be impossible to support filter clauses with it.
6625 The trampolines need a predictable call sequence, since they need to disasm
6626 the calling code to obtain register numbers / offsets.
6628 LLVM currently generates this code in non-JIT mode:
6629 mov -0x98(%rax),%eax
6631 Here, the vtable pointer is lost.
6632 -> solution: use one vtable trampoline per class.
6634 - passing/receiving the IMT pointer/RGCTX.
6635 -> solution: pass them as normal arguments ?
6639 LLVM does not allow the specification of argument registers etc. This means
6640 that all calls are made according to the platform ABI.
6642 - passing/receiving vtypes.
6644 Vtypes passed/received in registers are handled by the front end by using
6645 a signature with scalar arguments, and loading the parts of the vtype into those
6648 Vtypes passed on the stack are handled using the 'byval' attribute.
6652 Supported though alloca, we need to emit the load/store code.
6656 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6657 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6658 This is made easier because the IR is already in SSA form.
6659 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6660 types are frequently used incorrectly.
6665 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6666 it with the file containing the methods emitted by the JIT and the AOT data
6670 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6671 * - each bblock should end with a branch
6672 * - setting the return value, making cfg->ret non-volatile
6673 * - avoid some transformations in the JIT which make it harder for us to generate
6675 * - use pointer types to help optimizations.