2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 LLVMValueRef generic_class_init_tramp;
50 GHashTable *llvm_types;
52 const char *got_symbol;
53 GHashTable *plt_entries;
54 GHashTable *plt_entries_ji;
55 GHashTable *method_to_lmethod;
60 GPtrArray *subprogram_mds;
62 LLVMExecutionEngineRef ee;
63 gboolean external_symbols;
68 MonoAssembly *assembly;
70 MonoAotFileInfo aot_info;
71 const char *jit_got_symbol;
72 const char *eh_frame_symbol;
73 LLVMValueRef code_start, code_end;
74 gboolean has_jitted_code;
79 * Information associated by the backend with mono basic blocks.
82 LLVMBasicBlockRef bblock, end_bblock;
83 LLVMValueRef finally_ind;
84 gboolean added, invoke_target;
86 * If this bblock is the start of a finally clause, this is a list of bblocks it
87 * needs to branch to in ENDFINALLY.
89 GSList *call_handler_return_bbs;
91 * If this bblock is the start of a finally clause, this is the bblock that
92 * CALL_HANDLER needs to branch to.
94 LLVMBasicBlockRef call_handler_target_bb;
95 /* The list of switch statements generated by ENDFINALLY instructions */
96 GSList *endfinally_switch_ins_list;
101 * Structure containing emit state
104 MonoMemPool *mempool;
106 /* Maps method names to the corresponding LLVMValueRef */
107 GHashTable *emitted_method_decls;
110 LLVMValueRef lmethod;
111 MonoLLVMModule *lmodule;
112 LLVMModuleRef module;
114 int sindex, default_index, ex_index;
115 LLVMBuilderRef builder;
116 LLVMValueRef *values, *addresses;
117 MonoType **vreg_cli_types;
119 MonoMethodSignature *sig;
121 GHashTable *region_to_handler;
122 GHashTable *clause_to_handler;
123 LLVMBuilderRef alloca_builder;
124 LLVMValueRef last_alloca;
125 LLVMValueRef rgctx_arg;
126 LLVMTypeRef *vreg_types;
128 gboolean *unreachable;
130 LLVMValueRef imt_rgctx_loc;
131 GHashTable *llvm_types;
133 MonoDebugMethodInfo *minfo;
135 /* For every clause, the clauses it is nested in */
143 MonoBasicBlock *in_bb;
148 * Instruction metadata
149 * This is the same as ins_info, but LREG != IREG.
157 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
158 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
165 /* keep in sync with the enum in mini.h */
168 #include "mini-ops.h"
173 #if SIZEOF_VOID_P == 4
174 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
176 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
179 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
182 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
184 #define TRACE_FAILURE(msg)
188 #define IS_TARGET_X86 1
190 #define IS_TARGET_X86 0
194 #define IS_TARGET_AMD64 1
196 #define IS_TARGET_AMD64 0
199 #define LLVM_FAILURE(ctx, reason) do { \
200 TRACE_FAILURE (reason); \
201 (ctx)->cfg->exception_message = g_strdup (reason); \
202 (ctx)->cfg->disable_llvm = TRUE; \
206 #define CHECK_FAILURE(ctx) do { \
207 if ((ctx)->cfg->disable_llvm) \
211 static LLVMIntPredicate cond_to_llvm_cond [] = {
224 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
237 static MonoNativeTlsKey current_cfg_tls_id;
239 static MonoLLVMModule aot_module;
240 static int memset_param_count, memcpy_param_count;
241 static const char *memset_func_name;
242 static const char *memcpy_func_name;
244 static void init_jit_module (MonoDomain *domain);
246 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
247 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
248 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
253 * The LLVM type with width == sizeof (gpointer)
258 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
264 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
270 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
276 * Return the size of the LLVM representation of the vtype T.
279 get_vtype_size (MonoType *t)
283 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
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 (ctx->cfg, 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 (ctx->cfg, sig->ret);
1177 ret_type = type_to_llvm_type (ctx, rtype);
1178 CHECK_FAILURE (ctx);
1181 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1182 /* LLVM models this by returning an aggregate value */
1183 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1184 LLVMTypeRef members [2];
1186 members [0] = IntPtrType ();
1187 ret_type = LLVMStructType (members, 1, FALSE);
1189 g_assert_not_reached ();
1191 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1192 /* Vtype returned normally by val */
1193 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1194 /* Vtype returned as a fp struct */
1195 LLVMTypeRef members [16];
1197 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1198 for (i = 0; i < cinfo->ret.nslots; ++i)
1199 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1200 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1201 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1202 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1204 ret_type = LLVMVoidType ();
1208 pindexes = g_new0 (int, sig->param_count);
1209 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1211 if (cinfo && cinfo->rgctx_arg) {
1213 sinfo->rgctx_arg_pindex = pindex;
1214 param_types [pindex] = ctx->lmodule->ptr_type;
1217 if (cinfo && cinfo->imt_arg) {
1219 sinfo->imt_arg_pindex = pindex;
1220 param_types [pindex] = ctx->lmodule->ptr_type;
1224 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1225 vret_arg_pindex = pindex;
1226 if (cinfo->vret_arg_index == 1) {
1227 /* Add the slots consumed by the first argument */
1228 LLVMArgInfo *ainfo = &cinfo->args [0];
1229 switch (ainfo->storage) {
1230 case LLVMArgVtypeInReg:
1231 for (j = 0; j < 2; ++j) {
1232 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1242 sinfo->vret_arg_pindex = vret_arg_pindex;
1245 if (vretaddr && vret_arg_pindex == pindex)
1246 param_types [pindex ++] = IntPtrType ();
1249 sinfo->this_arg_pindex = pindex;
1250 param_types [pindex ++] = ThisType ();
1252 if (vretaddr && vret_arg_pindex == pindex)
1253 param_types [pindex ++] = IntPtrType ();
1254 for (i = 0; i < sig->param_count; ++i) {
1255 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1257 if (vretaddr && vret_arg_pindex == pindex)
1258 param_types [pindex ++] = IntPtrType ();
1259 pindexes [i] = pindex;
1262 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1266 switch (ainfo->storage) {
1267 case LLVMArgVtypeInReg:
1268 for (j = 0; j < 2; ++j) {
1269 switch (ainfo->pair_storage [j]) {
1271 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1276 g_assert_not_reached ();
1280 case LLVMArgVtypeByVal:
1281 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1282 CHECK_FAILURE (ctx);
1283 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1286 case LLVMArgAsIArgs:
1287 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1290 case LLVMArgAsFpArgs: {
1293 for (j = 0; j < ainfo->nslots; ++j)
1294 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1295 pindex += ainfo->nslots;
1299 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1303 if (vretaddr && vret_arg_pindex == pindex)
1304 param_types [pindex ++] = IntPtrType ();
1306 CHECK_FAILURE (ctx);
1308 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1309 g_free (param_types);
1312 sinfo->pindexes = pindexes;
1320 g_free (param_types);
1326 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1328 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1332 * LLVMFunctionType1:
1334 * Create an LLVM function type from the arguments.
1336 static G_GNUC_UNUSED LLVMTypeRef
1337 LLVMFunctionType1(LLVMTypeRef ReturnType,
1338 LLVMTypeRef ParamType1,
1341 LLVMTypeRef param_types [1];
1343 param_types [0] = ParamType1;
1345 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1349 * LLVMFunctionType2:
1351 * Create an LLVM function type from the arguments.
1353 static G_GNUC_UNUSED LLVMTypeRef
1354 LLVMFunctionType2(LLVMTypeRef ReturnType,
1355 LLVMTypeRef ParamType1,
1356 LLVMTypeRef ParamType2,
1359 LLVMTypeRef param_types [2];
1361 param_types [0] = ParamType1;
1362 param_types [1] = ParamType2;
1364 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1368 * LLVMFunctionType3:
1370 * Create an LLVM function type from the arguments.
1372 static G_GNUC_UNUSED LLVMTypeRef
1373 LLVMFunctionType3(LLVMTypeRef ReturnType,
1374 LLVMTypeRef ParamType1,
1375 LLVMTypeRef ParamType2,
1376 LLVMTypeRef ParamType3,
1379 LLVMTypeRef param_types [3];
1381 param_types [0] = ParamType1;
1382 param_types [1] = ParamType2;
1383 param_types [2] = ParamType3;
1385 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1391 * Create an LLVM builder and remember it so it can be freed later.
1393 static LLVMBuilderRef
1394 create_builder (EmitContext *ctx)
1396 LLVMBuilderRef builder = LLVMCreateBuilder ();
1398 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1404 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1406 char *callee_name = mono_aot_get_plt_symbol (type, data);
1407 LLVMValueRef callee;
1408 MonoJumpInfo *ji = NULL;
1413 if (ctx->cfg->compile_aot)
1414 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1415 mono_add_patch_info (ctx->cfg, 0, type, data);
1418 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1420 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1422 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1424 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1427 if (ctx->cfg->compile_aot) {
1428 ji = g_new0 (MonoJumpInfo, 1);
1430 ji->data.target = data;
1432 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1439 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1441 MonoMethodHeader *header = cfg->header;
1442 MonoExceptionClause *clause;
1446 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1447 return (bb->region >> 8) - 1;
1450 for (i = 0; i < header->num_clauses; ++i) {
1451 clause = &header->clauses [i];
1453 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1461 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1463 LLVMValueRef md_arg;
1466 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1467 md_arg = LLVMMDString ("mono", 4);
1468 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1472 set_invariant_load_flag (LLVMValueRef v)
1474 LLVMValueRef md_arg;
1476 const char *flag_name;
1478 // FIXME: Cache this
1479 flag_name = "invariant.load";
1480 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1481 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1482 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1488 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1492 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1494 MonoCompile *cfg = ctx->cfg;
1496 LLVMBuilderRef builder = *builder_ref;
1499 clause_index = get_handler_clause (cfg, bb);
1501 if (clause_index != -1) {
1502 MonoMethodHeader *header = cfg->header;
1503 MonoExceptionClause *ec = &header->clauses [clause_index];
1504 MonoBasicBlock *tblock;
1505 LLVMBasicBlockRef ex_bb, noex_bb;
1508 * Have to use an invoke instead of a call, branching to the
1509 * handler bblock of the clause containing this bblock.
1512 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1514 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1517 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1519 ex_bb = get_bb (ctx, tblock);
1521 noex_bb = gen_bb (ctx, "NOEX_BB");
1524 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1526 builder = ctx->builder = create_builder (ctx);
1527 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1529 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1531 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1532 ctx->builder = builder;
1535 *builder_ref = ctx->builder;
1541 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1543 const char *intrins_name;
1544 LLVMValueRef args [16], res;
1545 LLVMTypeRef addr_type;
1547 if (is_faulting && bb->region != -1) {
1548 LLVMAtomicOrdering ordering;
1551 case LLVM_BARRIER_NONE:
1552 ordering = LLVMAtomicOrderingNotAtomic;
1554 case LLVM_BARRIER_ACQ:
1555 ordering = LLVMAtomicOrderingAcquire;
1557 case LLVM_BARRIER_SEQ:
1558 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1561 g_assert_not_reached ();
1566 * We handle loads which can fault by calling a mono specific intrinsic
1567 * using an invoke, so they are handled properly inside try blocks.
1568 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1569 * are marked with IntrReadArgMem.
1573 intrins_name = "llvm.mono.load.i8.p0i8";
1576 intrins_name = "llvm.mono.load.i16.p0i16";
1579 intrins_name = "llvm.mono.load.i32.p0i32";
1582 intrins_name = "llvm.mono.load.i64.p0i64";
1585 g_assert_not_reached ();
1588 addr_type = LLVMTypeOf (addr);
1589 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1590 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1593 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1594 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1595 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1596 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1598 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1599 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1600 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1601 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1608 * We emit volatile loads for loads which can fault, because otherwise
1609 * LLVM will generate invalid code when encountering a load from a
1612 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1614 /* Mark it with a custom metadata */
1617 set_metadata_flag (res, "mono.faulting.load");
1625 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1627 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1631 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1633 const char *intrins_name;
1634 LLVMValueRef args [16];
1636 if (is_faulting && bb->region != -1) {
1637 LLVMAtomicOrdering ordering;
1640 case LLVM_BARRIER_NONE:
1641 ordering = LLVMAtomicOrderingNotAtomic;
1643 case LLVM_BARRIER_REL:
1644 ordering = LLVMAtomicOrderingRelease;
1646 case LLVM_BARRIER_SEQ:
1647 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1650 g_assert_not_reached ();
1656 intrins_name = "llvm.mono.store.i8.p0i8";
1659 intrins_name = "llvm.mono.store.i16.p0i16";
1662 intrins_name = "llvm.mono.store.i32.p0i32";
1665 intrins_name = "llvm.mono.store.i64.p0i64";
1668 g_assert_not_reached ();
1671 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1672 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1673 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1678 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1679 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1680 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1681 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1683 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1688 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1690 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1694 * emit_cond_system_exception:
1696 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1697 * Might set the ctx exception.
1700 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1702 LLVMBasicBlockRef ex_bb, noex_bb;
1703 LLVMBuilderRef builder;
1704 MonoClass *exc_class;
1705 LLVMValueRef args [2];
1707 ex_bb = gen_bb (ctx, "EX_BB");
1708 noex_bb = gen_bb (ctx, "NOEX_BB");
1710 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1712 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1713 g_assert (exc_class);
1715 /* Emit exception throwing code */
1716 builder = create_builder (ctx);
1717 LLVMPositionBuilderAtEnd (builder, ex_bb);
1719 if (!ctx->lmodule->throw_corlib_exception) {
1720 LLVMValueRef callee;
1722 const char *icall_name;
1724 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1725 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1726 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1727 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1728 /* This will become i8* */
1729 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1730 sig = sig_to_llvm_sig (ctx, throw_sig);
1732 if (ctx->cfg->compile_aot) {
1733 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1735 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1738 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1739 * - On x86, LLVM generated code doesn't push the arguments
1740 * - The trampoline takes the throw address as an arguments, not a pc offset.
1742 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1745 mono_memory_barrier ();
1746 ctx->lmodule->throw_corlib_exception = callee;
1749 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1750 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1752 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1755 * The LLVM mono branch contains changes so a block address can be passed as an
1756 * argument to a call.
1758 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1759 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1761 LLVMBuildUnreachable (builder);
1763 ctx->builder = create_builder (ctx);
1764 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1766 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1773 * emit_args_to_vtype:
1775 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1778 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1780 int j, size, nslots;
1782 size = get_vtype_size (t);
1784 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1785 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1788 if (ainfo->storage == LLVMArgAsFpArgs)
1789 nslots = ainfo->nslots;
1793 for (j = 0; j < nslots; ++j) {
1794 LLVMValueRef index [2], addr, daddr;
1795 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1796 LLVMTypeRef part_type;
1798 if (ainfo->pair_storage [j] == LLVMArgNone)
1801 switch (ainfo->pair_storage [j]) {
1802 case LLVMArgInIReg: {
1803 part_type = LLVMIntType (part_size * 8);
1804 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1805 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1806 addr = LLVMBuildGEP (builder, address, index, 1, "");
1808 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1809 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1810 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1812 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1815 case LLVMArgInFPReg: {
1816 LLVMTypeRef arg_type;
1818 if (ainfo->esize == 8)
1819 arg_type = LLVMDoubleType ();
1821 arg_type = LLVMFloatType ();
1823 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1824 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1825 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1826 LLVMBuildStore (builder, args [j], addr);
1832 g_assert_not_reached ();
1835 size -= sizeof (gpointer);
1840 * emit_vtype_to_args:
1842 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1843 * into ARGS, and the number of arguments into NARGS.
1846 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1849 int j, size, nslots;
1850 LLVMTypeRef arg_type;
1852 size = get_vtype_size (t);
1854 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1855 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1857 if (ainfo->storage == LLVMArgAsFpArgs)
1858 nslots = ainfo->nslots;
1861 for (j = 0; j < nslots; ++j) {
1862 LLVMValueRef index [2], addr, daddr;
1863 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1865 if (ainfo->pair_storage [j] == LLVMArgNone)
1868 switch (ainfo->pair_storage [j]) {
1870 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1871 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1872 addr = LLVMBuildGEP (builder, address, index, 1, "");
1874 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1875 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1876 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1878 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1880 case LLVMArgInFPReg:
1881 if (ainfo->esize == 8)
1882 arg_type = LLVMDoubleType ();
1884 arg_type = LLVMFloatType ();
1885 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1886 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1887 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1888 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1893 g_assert_not_reached ();
1895 size -= sizeof (gpointer);
1902 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1905 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1906 * get executed every time control reaches them.
1908 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1910 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1911 return ctx->last_alloca;
1915 build_alloca (EmitContext *ctx, MonoType *t)
1917 MonoClass *k = mono_class_from_mono_type (t);
1920 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1923 align = mono_class_min_align (k);
1925 /* Sometimes align is not a power of 2 */
1926 while (mono_is_power_of_two (align) == -1)
1929 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1933 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1936 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1939 lmodule->used = g_ptr_array_sized_new (16);
1940 g_ptr_array_add (lmodule->used, global);
1944 emit_llvm_used (MonoLLVMModule *lmodule)
1946 LLVMModuleRef module = lmodule->module;
1947 LLVMTypeRef used_type;
1948 LLVMValueRef used, *used_elem;
1954 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1955 used = LLVMAddGlobal (module, used_type, "llvm.used");
1956 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1957 for (i = 0; i < lmodule->used->len; ++i)
1958 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1959 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1960 LLVMSetLinkage (used, LLVMAppendingLinkage);
1961 LLVMSetSection (used, "llvm.metadata");
1965 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1967 gboolean need_div_check = FALSE;
1969 #ifdef MONO_ARCH_NEED_DIV_CHECK
1970 need_div_check = TRUE;
1973 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1974 need_div_check = TRUE;
1976 if (!need_div_check)
1979 switch (ins->opcode) {
1992 case OP_IDIV_UN_IMM:
1993 case OP_LDIV_UN_IMM:
1994 case OP_IREM_UN_IMM:
1995 case OP_LREM_UN_IMM: {
1997 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1998 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2000 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2001 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2002 CHECK_FAILURE (ctx);
2003 builder = ctx->builder;
2005 /* b == -1 && a == 0x80000000 */
2007 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2008 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2009 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2011 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2012 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2013 CHECK_FAILURE (ctx);
2014 builder = ctx->builder;
2029 * Emit code to load/convert arguments.
2032 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2035 MonoCompile *cfg = ctx->cfg;
2036 MonoMethodSignature *sig = ctx->sig;
2037 LLVMCallInfo *linfo = ctx->linfo;
2040 ctx->alloca_builder = create_builder (ctx);
2043 * Handle indirect/volatile variables by allocating memory for them
2044 * using 'alloca', and storing their address in a temporary.
2046 for (i = 0; i < cfg->num_varinfo; ++i) {
2047 MonoInst *var = cfg->varinfo [i];
2050 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2051 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2052 CHECK_FAILURE (ctx);
2053 /* Could be already created by an OP_VPHI */
2054 if (!ctx->addresses [var->dreg])
2055 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2056 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2060 for (i = 0; i < sig->param_count; ++i) {
2061 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2062 int reg = cfg->args [i + sig->hasthis]->dreg;
2064 switch (ainfo->storage) {
2065 case LLVMArgVtypeInReg:
2066 case LLVMArgAsFpArgs: {
2067 LLVMValueRef args [8];
2070 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2071 memset (args, 0, sizeof (args));
2072 pindex = ctx->pindexes [i];
2073 if (ainfo->storage == LLVMArgVtypeInReg) {
2074 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2075 if (ainfo->pair_storage [1] != LLVMArgNone)
2076 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2078 g_assert (ainfo->nslots <= 8);
2079 for (j = 0; j < ainfo->nslots; ++j)
2080 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2082 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2084 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2086 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2087 /* Treat these as normal values */
2088 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2092 case LLVMArgVtypeByVal: {
2093 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2095 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2096 /* Treat these as normal values */
2097 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2101 case LLVMArgAsIArgs: {
2102 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2104 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2106 /* The argument is received as an array of ints, store it into the real argument */
2107 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2111 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]));
2117 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2119 emit_volatile_store (ctx, cfg->args [0]->dreg);
2120 for (i = 0; i < sig->param_count; ++i)
2121 if (!mini_type_is_vtype (cfg, sig->params [i]))
2122 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2124 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2125 LLVMValueRef this_alloc;
2128 * The exception handling code needs the location where the this argument was
2129 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2130 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2131 * location into the LSDA.
2133 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2134 /* This volatile store will keep the alloca alive */
2135 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2137 set_metadata_flag (this_alloc, "mono.this");
2140 if (cfg->rgctx_var) {
2141 LLVMValueRef rgctx_alloc, store;
2144 * We handle the rgctx arg similarly to the this pointer.
2146 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2147 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2148 /* This volatile store will keep the alloca alive */
2149 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2151 set_metadata_flag (rgctx_alloc, "mono.this");
2154 /* Compute nesting between clauses */
2155 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2156 for (i = 0; i < cfg->header->num_clauses; ++i) {
2157 for (j = 0; j < cfg->header->num_clauses; ++j) {
2158 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2159 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2161 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2162 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2167 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2168 * it needs to continue normally, or return back to the exception handling system.
2170 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2174 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2177 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2178 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2179 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2181 if (bb->in_scount == 0) {
2184 sprintf (name, "finally_ind_bb%d", bb->block_num);
2185 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2186 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2188 ctx->bblocks [bb->block_num].finally_ind = val;
2190 /* Create a variable to hold the exception var */
2192 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2196 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2197 * LLVM bblock containing a landing pad causes problems for the
2198 * LLVM optimizer passes.
2200 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2201 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2208 /* Have to export this for AOT */
2210 mono_personality (void)
2213 g_assert_not_reached ();
2217 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2219 MonoCompile *cfg = ctx->cfg;
2220 LLVMModuleRef module = ctx->module;
2221 LLVMValueRef *values = ctx->values;
2222 LLVMValueRef *addresses = ctx->addresses;
2223 MonoCallInst *call = (MonoCallInst*)ins;
2224 MonoMethodSignature *sig = call->signature;
2225 LLVMValueRef callee = NULL, lcall;
2227 LLVMCallInfo *cinfo;
2231 LLVMTypeRef llvm_sig;
2233 gboolean virtual, calli;
2234 LLVMBuilderRef builder = *builder_ref;
2237 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2238 LLVM_FAILURE (ctx, "non-default callconv");
2240 cinfo = call->cinfo;
2241 if (call->rgctx_arg_reg)
2242 cinfo->rgctx_arg = TRUE;
2243 if (call->imt_arg_reg)
2244 cinfo->imt_arg = TRUE;
2246 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2248 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2249 CHECK_FAILURE (ctx);
2251 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);
2252 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);
2254 /* FIXME: Avoid creating duplicate methods */
2256 if (ins->flags & MONO_INST_HAS_METHOD) {
2260 if (cfg->compile_aot) {
2261 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2263 LLVM_FAILURE (ctx, "can't encode patch");
2265 callee = LLVMAddFunction (module, "", llvm_sig);
2268 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2270 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2274 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2275 /* LLVM miscompiles async methods */
2276 LLVM_FAILURE (ctx, "#13734");
2279 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2285 memset (&ji, 0, sizeof (ji));
2286 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2287 ji.data.target = info->name;
2289 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2291 if (cfg->compile_aot) {
2292 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2294 LLVM_FAILURE (ctx, "can't encode patch");
2296 callee = LLVMAddFunction (module, "", llvm_sig);
2297 target = (gpointer)mono_icall_get_wrapper (info);
2298 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2301 if (cfg->compile_aot) {
2303 if (cfg->abs_patches) {
2304 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2306 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2308 LLVM_FAILURE (ctx, "can't encode patch");
2312 LLVM_FAILURE (ctx, "aot");
2314 callee = LLVMAddFunction (module, "", llvm_sig);
2316 if (cfg->abs_patches) {
2317 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2320 * FIXME: Some trampolines might have
2321 * their own calling convention on some platforms.
2323 #ifndef TARGET_AMD64
2324 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2325 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2326 LLVM_FAILURE (ctx, "trampoline with own cconv");
2328 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2329 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2333 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2339 int size = sizeof (gpointer);
2342 g_assert (ins->inst_offset % size == 0);
2343 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2345 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2347 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2349 if (ins->flags & MONO_INST_HAS_METHOD) {
2354 * Collect and convert arguments
2356 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2357 len = sizeof (LLVMValueRef) * nargs;
2358 args = alloca (len);
2359 memset (args, 0, len);
2360 l = call->out_ireg_args;
2362 if (call->rgctx_arg_reg) {
2363 g_assert (values [call->rgctx_arg_reg]);
2364 g_assert (sinfo.rgctx_arg_pindex < nargs);
2366 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2367 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2368 * it using a volatile load.
2371 if (!ctx->imt_rgctx_loc)
2372 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2373 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2374 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2376 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2379 if (call->imt_arg_reg) {
2380 g_assert (values [call->imt_arg_reg]);
2381 g_assert (sinfo.imt_arg_pindex < nargs);
2383 if (!ctx->imt_rgctx_loc)
2384 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2385 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2386 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2388 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2393 if (!addresses [call->inst.dreg])
2394 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2395 g_assert (sinfo.vret_arg_pindex < nargs);
2396 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2399 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2402 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2406 pindex = sinfo.this_arg_pindex;
2408 pindex = sinfo.pindexes [i - 1];
2410 pindex = sinfo.pindexes [i];
2413 regpair = (guint32)(gssize)(l->data);
2414 reg = regpair & 0xffffff;
2415 args [pindex] = values [reg];
2416 switch (ainfo->storage) {
2417 case LLVMArgVtypeInReg:
2418 case LLVMArgAsFpArgs: {
2421 g_assert (addresses [reg]);
2422 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2426 // FIXME: Get rid of the VMOVE
2429 case LLVMArgVtypeByVal:
2430 g_assert (addresses [reg]);
2431 args [pindex] = addresses [reg];
2433 case LLVMArgAsIArgs:
2434 g_assert (addresses [reg]);
2435 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2438 g_assert (args [pindex]);
2439 if (i == 0 && sig->hasthis)
2440 args [pindex] = convert (ctx, args [pindex], ThisType ());
2442 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2445 g_assert (pindex <= nargs);
2450 // FIXME: Align call sites
2456 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2459 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2461 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2462 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2464 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2465 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2467 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2469 if (call->rgctx_arg_reg)
2470 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2471 if (call->imt_arg_reg)
2472 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2474 /* Add byval attributes if needed */
2475 for (i = 0; i < sig->param_count; ++i) {
2476 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2478 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2479 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2484 * Convert the result
2487 switch (cinfo->ret.storage) {
2488 case LLVMArgVtypeInReg: {
2489 LLVMValueRef regs [2];
2491 if (!addresses [ins->dreg])
2492 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2494 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2495 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2496 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2497 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2500 case LLVMArgVtypeByVal:
2501 if (!addresses [call->inst.dreg])
2502 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2503 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2505 case LLVMArgFpStruct:
2506 if (!addresses [call->inst.dreg])
2507 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2508 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2511 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2512 /* If the method returns an unsigned value, need to zext it */
2513 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));
2517 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2518 /* If the method returns an unsigned value, need to zext it */
2519 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));
2523 if (!addresses [call->inst.dreg])
2524 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2525 g_assert (sinfo.vret_arg_pindex < nargs);
2526 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2529 *builder_ref = ctx->builder;
2531 g_free (sinfo.pindexes);
2539 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2541 MonoCompile *cfg = ctx->cfg;
2542 LLVMValueRef *values = ctx->values;
2543 LLVMModuleRef module = ctx->module;
2544 BBInfo *bblocks = ctx->bblocks;
2546 LLVMValueRef personality;
2547 LLVMValueRef landing_pad;
2548 LLVMBasicBlockRef target_bb;
2550 static gint32 mapping_inited;
2551 static int ti_generator;
2554 LLVMValueRef type_info;
2558 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2560 if (cfg->compile_aot) {
2561 /* Use a dummy personality function */
2562 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2563 g_assert (personality);
2565 personality = LLVMGetNamedFunction (module, "mono_personality");
2566 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2567 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2570 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2572 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2575 * Create the type info
2577 sprintf (ti_name, "type_info_%d", ti_generator);
2580 if (cfg->compile_aot) {
2581 /* decode_eh_frame () in aot-runtime.c will decode this */
2582 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2583 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2586 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2588 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2591 * After the cfg mempool is freed, the type info will point to stale memory,
2592 * but this is not a problem, since we decode it once in exception_cb during
2595 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2596 *(gint32*)ti = clause_index;
2598 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2600 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2604 LLVMTypeRef members [2], ret_type;
2606 members [0] = i8ptr;
2607 members [1] = LLVMInt32Type ();
2608 ret_type = LLVMStructType (members, 2, FALSE);
2610 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2611 LLVMAddClause (landing_pad, type_info);
2613 /* Store the exception into the exvar */
2615 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2619 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2620 * code expects control to be transferred to this landing pad even in the
2621 * presence of nested clauses. The landing pad needs to branch to the landing
2622 * pads belonging to nested clauses based on the selector value returned by
2623 * the landing pad instruction, which is passed to the landing pad in a
2624 * register by the EH code.
2626 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2627 g_assert (target_bb);
2630 * Branch to the correct landing pad
2632 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2633 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2635 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2636 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2637 MonoBasicBlock *handler_bb;
2639 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2640 g_assert (handler_bb);
2642 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2643 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2646 /* Start a new bblock which CALL_HANDLER can branch to */
2647 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2649 ctx->builder = builder = create_builder (ctx);
2650 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2652 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2654 /* Store the exception into the IL level exvar */
2655 if (bb->in_scount == 1) {
2656 g_assert (bb->in_scount == 1);
2657 exvar = bb->in_stack [0];
2659 // FIXME: This is shared with filter clauses ?
2660 g_assert (!values [exvar->dreg]);
2662 g_assert (ctx->ex_var);
2663 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2664 emit_volatile_store (ctx, exvar->dreg);
2670 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2672 MonoCompile *cfg = ctx->cfg;
2673 MonoMethodSignature *sig = ctx->sig;
2674 LLVMValueRef method = ctx->lmethod;
2675 LLVMValueRef *values = ctx->values;
2676 LLVMValueRef *addresses = ctx->addresses;
2677 LLVMCallInfo *linfo = ctx->linfo;
2678 LLVMModuleRef module = ctx->module;
2679 BBInfo *bblocks = ctx->bblocks;
2681 LLVMBasicBlockRef cbb;
2682 LLVMBuilderRef builder, starting_builder;
2683 gboolean has_terminator;
2685 LLVMValueRef lhs, rhs;
2688 cbb = get_bb (ctx, bb);
2689 builder = create_builder (ctx);
2690 ctx->builder = builder;
2691 LLVMPositionBuilderAtEnd (builder, cbb);
2693 if (bb == cfg->bb_entry)
2694 emit_entry_bb (ctx, builder);
2695 CHECK_FAILURE (ctx);
2697 if (bb->flags & BB_EXCEPTION_HANDLER) {
2698 if (!bblocks [bb->block_num].invoke_target) {
2700 * LLVM asserts if llvm.eh.selector is called from a bblock which
2701 * doesn't have an invoke pointing at it.
2702 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2704 LLVM_FAILURE (ctx, "handler without invokes");
2707 emit_handler_start (ctx, bb, builder);
2708 CHECK_FAILURE (ctx);
2709 builder = ctx->builder;
2712 has_terminator = FALSE;
2713 starting_builder = builder;
2714 for (ins = bb->code; ins; ins = ins->next) {
2715 const char *spec = LLVM_INS_INFO (ins->opcode);
2717 char dname_buf [128];
2719 emit_dbg_loc (ctx, builder, ins->cil_code);
2722 if (nins > 3000 && builder == starting_builder) {
2723 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2724 LLVM_FAILURE (ctx, "basic block too long");
2728 /* There could be instructions after a terminator, skip them */
2731 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2732 sprintf (dname_buf, "t%d", ins->dreg);
2736 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2737 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2739 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2740 lhs = emit_volatile_load (ctx, ins->sreg1);
2742 /* It is ok for SETRET to have an uninitialized argument */
2743 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2744 LLVM_FAILURE (ctx, "sreg1");
2745 lhs = values [ins->sreg1];
2751 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2752 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2753 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2754 rhs = emit_volatile_load (ctx, ins->sreg2);
2756 if (!values [ins->sreg2])
2757 LLVM_FAILURE (ctx, "sreg2");
2758 rhs = values [ins->sreg2];
2764 //mono_print_ins (ins);
2765 switch (ins->opcode) {
2768 case OP_LIVERANGE_START:
2769 case OP_LIVERANGE_END:
2772 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2775 #if SIZEOF_VOID_P == 4
2776 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2778 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2782 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2786 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2788 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2790 case OP_DUMMY_ICONST:
2791 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2793 case OP_DUMMY_I8CONST:
2794 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2796 case OP_DUMMY_R8CONST:
2797 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2800 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2801 has_terminator = TRUE;
2807 LLVMBasicBlockRef new_bb;
2808 LLVMBuilderRef new_builder;
2810 // The default branch is already handled
2811 // FIXME: Handle it here
2813 /* Start new bblock */
2814 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2815 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2817 lhs = convert (ctx, lhs, LLVMInt32Type ());
2818 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2819 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2820 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2822 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2825 new_builder = create_builder (ctx);
2826 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2827 LLVMBuildUnreachable (new_builder);
2829 has_terminator = TRUE;
2830 g_assert (!ins->next);
2836 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2837 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2838 LLVMValueRef part1, retval;
2841 size = get_vtype_size (sig->ret);
2843 g_assert (addresses [ins->sreg1]);
2845 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2846 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2848 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2850 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2852 LLVMBuildRet (builder, retval);
2856 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2857 LLVMValueRef retval;
2859 g_assert (addresses [ins->sreg1]);
2860 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2861 LLVMBuildRet (builder, retval);
2865 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2866 LLVMBuildRetVoid (builder);
2870 if (linfo->ret.storage == LLVMArgFpStruct) {
2871 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2872 LLVMValueRef retval;
2874 g_assert (addresses [ins->sreg1]);
2875 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2876 LLVMBuildRet (builder, retval);
2880 if (!lhs || ctx->is_dead [ins->sreg1]) {
2882 * The method did not set its return value, probably because it
2883 * ends with a throw.
2886 LLVMBuildRetVoid (builder);
2888 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2890 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2892 has_terminator = TRUE;
2899 case OP_ICOMPARE_IMM:
2900 case OP_LCOMPARE_IMM:
2901 case OP_COMPARE_IMM: {
2905 if (ins->next->opcode == OP_NOP)
2908 if (ins->next->opcode == OP_BR)
2909 /* The comparison result is not needed */
2912 rel = mono_opcode_to_cond (ins->next->opcode);
2914 if (ins->opcode == OP_ICOMPARE_IMM) {
2915 lhs = convert (ctx, lhs, LLVMInt32Type ());
2916 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2918 if (ins->opcode == OP_LCOMPARE_IMM) {
2919 lhs = convert (ctx, lhs, LLVMInt64Type ());
2920 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2922 if (ins->opcode == OP_LCOMPARE) {
2923 lhs = convert (ctx, lhs, LLVMInt64Type ());
2924 rhs = convert (ctx, rhs, LLVMInt64Type ());
2926 if (ins->opcode == OP_ICOMPARE) {
2927 lhs = convert (ctx, lhs, LLVMInt32Type ());
2928 rhs = convert (ctx, rhs, LLVMInt32Type ());
2932 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2933 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2934 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2935 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2938 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2939 if (ins->opcode == OP_FCOMPARE) {
2940 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2941 } else if (ins->opcode == OP_RCOMPARE) {
2942 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2943 } else if (ins->opcode == OP_COMPARE_IMM) {
2944 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2945 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2947 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2948 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2949 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2950 /* The immediate is encoded in two fields */
2951 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2952 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2954 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2957 else if (ins->opcode == OP_COMPARE) {
2958 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2959 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2961 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2963 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2965 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2966 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2968 * If the target bb contains PHI instructions, LLVM requires
2969 * two PHI entries for this bblock, while we only generate one.
2970 * So convert this to an unconditional bblock. (bxc #171).
2972 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2974 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2976 has_terminator = TRUE;
2977 } else if (MONO_IS_SETCC (ins->next)) {
2978 sprintf (dname_buf, "t%d", ins->next->dreg);
2980 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2982 /* Add stores for volatile variables */
2983 emit_volatile_store (ctx, ins->next->dreg);
2984 } else if (MONO_IS_COND_EXC (ins->next)) {
2985 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2986 CHECK_FAILURE (ctx);
2987 builder = ctx->builder;
2989 LLVM_FAILURE (ctx, "next");
3003 rel = mono_opcode_to_cond (ins->opcode);
3005 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3006 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3017 rel = mono_opcode_to_cond (ins->opcode);
3019 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3020 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3028 gboolean empty = TRUE;
3030 /* Check that all input bblocks really branch to us */
3031 for (i = 0; i < bb->in_count; ++i) {
3032 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3033 ins->inst_phi_args [i + 1] = -1;
3039 /* LLVM doesn't like phi instructions with zero operands */
3040 ctx->is_dead [ins->dreg] = TRUE;
3044 /* Created earlier, insert it now */
3045 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3047 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3048 int sreg1 = ins->inst_phi_args [i + 1];
3052 * Count the number of times the incoming bblock branches to us,
3053 * since llvm requires a separate entry for each.
3055 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3056 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3059 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3060 if (switch_ins->inst_many_bb [j] == bb)
3067 /* Remember for later */
3068 for (j = 0; j < count; ++j) {
3069 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3072 node->in_bb = bb->in_bb [i];
3074 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);
3084 values [ins->dreg] = lhs;
3088 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3091 values [ins->dreg] = lhs;
3093 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3095 * This is added by the spilling pass in case of the JIT,
3096 * but we have to do it ourselves.
3098 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3102 case OP_MOVE_F_TO_I4: {
3103 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3106 case OP_MOVE_I4_TO_F: {
3107 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3110 case OP_MOVE_F_TO_I8: {
3111 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3114 case OP_MOVE_I8_TO_F: {
3115 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3148 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3149 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3151 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3152 CHECK_FAILURE (ctx);
3153 builder = ctx->builder;
3155 switch (ins->opcode) {
3158 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3162 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3166 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3170 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3174 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3178 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3182 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3186 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3190 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3194 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3198 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3202 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3206 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3210 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3214 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3217 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3220 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3224 g_assert_not_reached ();
3231 lhs = convert (ctx, lhs, LLVMFloatType ());
3232 rhs = convert (ctx, rhs, LLVMFloatType ());
3233 switch (ins->opcode) {
3235 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3238 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3241 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3244 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3247 g_assert_not_reached ();
3256 case OP_IREM_UN_IMM:
3258 case OP_IDIV_UN_IMM:
3264 case OP_ISHR_UN_IMM:
3273 case OP_LSHR_UN_IMM:
3279 case OP_SHR_UN_IMM: {
3282 if (spec [MONO_INST_SRC1] == 'l') {
3283 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3285 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3288 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3289 CHECK_FAILURE (ctx);
3290 builder = ctx->builder;
3292 #if SIZEOF_VOID_P == 4
3293 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3294 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3297 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3298 lhs = convert (ctx, lhs, IntPtrType ());
3299 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3300 switch (ins->opcode) {
3304 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3308 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3312 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3316 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3318 case OP_IDIV_UN_IMM:
3319 case OP_LDIV_UN_IMM:
3320 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3324 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3326 case OP_IREM_UN_IMM:
3327 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3332 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3336 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3340 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3345 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3350 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3352 case OP_ISHR_UN_IMM:
3353 /* This is used to implement conv.u4, so the lhs could be an i8 */
3354 lhs = convert (ctx, lhs, LLVMInt32Type ());
3355 imm = convert (ctx, imm, LLVMInt32Type ());
3356 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3358 case OP_LSHR_UN_IMM:
3360 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3363 g_assert_not_reached ();
3368 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3371 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3374 lhs = convert (ctx, lhs, LLVMDoubleType ());
3375 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3378 lhs = convert (ctx, lhs, LLVMFloatType ());
3379 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3382 guint32 v = 0xffffffff;
3383 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3387 guint64 v = 0xffffffffffffffffLL;
3388 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3391 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3393 LLVMValueRef v1, v2;
3395 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3396 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3397 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3402 case OP_ICONV_TO_I1:
3403 case OP_ICONV_TO_I2:
3404 case OP_ICONV_TO_I4:
3405 case OP_ICONV_TO_U1:
3406 case OP_ICONV_TO_U2:
3407 case OP_ICONV_TO_U4:
3408 case OP_LCONV_TO_I1:
3409 case OP_LCONV_TO_I2:
3410 case OP_LCONV_TO_U1:
3411 case OP_LCONV_TO_U2:
3412 case OP_LCONV_TO_U4: {
3415 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);
3417 /* Have to do two casts since our vregs have type int */
3418 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3420 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3422 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3425 case OP_ICONV_TO_I8:
3426 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3428 case OP_ICONV_TO_U8:
3429 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3431 case OP_FCONV_TO_I4:
3432 case OP_RCONV_TO_I4:
3433 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3435 case OP_FCONV_TO_I1:
3436 case OP_RCONV_TO_I1:
3437 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3439 case OP_FCONV_TO_U1:
3440 case OP_RCONV_TO_U1:
3441 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3443 case OP_FCONV_TO_I2:
3444 case OP_RCONV_TO_I2:
3445 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3447 case OP_FCONV_TO_U2:
3448 case OP_RCONV_TO_U2:
3449 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3451 case OP_FCONV_TO_I8:
3452 case OP_RCONV_TO_I8:
3453 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3456 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3458 case OP_ICONV_TO_R8:
3459 case OP_LCONV_TO_R8:
3460 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3462 case OP_LCONV_TO_R_UN:
3463 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3465 #if SIZEOF_VOID_P == 4
3468 case OP_LCONV_TO_I4:
3469 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3471 case OP_ICONV_TO_R4:
3472 case OP_LCONV_TO_R4:
3473 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3475 values [ins->dreg] = v;
3477 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3479 case OP_FCONV_TO_R4:
3480 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3482 values [ins->dreg] = v;
3484 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3486 case OP_RCONV_TO_R8:
3487 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3489 case OP_RCONV_TO_R4:
3490 values [ins->dreg] = lhs;
3493 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3496 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3499 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3501 case OP_LOCALLOC_IMM: {
3504 guint32 size = ins->inst_imm;
3505 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3507 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3509 if (ins->flags & MONO_INST_INIT) {
3510 LLVMValueRef args [5];
3513 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3514 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3515 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3516 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3517 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3520 values [ins->dreg] = v;
3524 LLVMValueRef v, size;
3526 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), "");
3528 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3530 if (ins->flags & MONO_INST_INIT) {
3531 LLVMValueRef args [5];
3534 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3536 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3537 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3538 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3540 values [ins->dreg] = v;
3544 case OP_LOADI1_MEMBASE:
3545 case OP_LOADU1_MEMBASE:
3546 case OP_LOADI2_MEMBASE:
3547 case OP_LOADU2_MEMBASE:
3548 case OP_LOADI4_MEMBASE:
3549 case OP_LOADU4_MEMBASE:
3550 case OP_LOADI8_MEMBASE:
3551 case OP_LOADR4_MEMBASE:
3552 case OP_LOADR8_MEMBASE:
3553 case OP_LOAD_MEMBASE:
3561 LLVMValueRef base, index, addr;
3563 gboolean sext = FALSE, zext = FALSE;
3564 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3566 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3571 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)) {
3572 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3577 if (ins->inst_offset == 0) {
3579 } else if (ins->inst_offset % size != 0) {
3580 /* Unaligned load */
3581 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3582 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3584 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3585 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3589 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3591 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3593 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3595 * These will signal LLVM that these loads do not alias any stores, and
3596 * they can't fail, allowing them to be hoisted out of loops.
3598 set_invariant_load_flag (values [ins->dreg]);
3599 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3603 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3605 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3606 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3607 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3611 case OP_STOREI1_MEMBASE_REG:
3612 case OP_STOREI2_MEMBASE_REG:
3613 case OP_STOREI4_MEMBASE_REG:
3614 case OP_STOREI8_MEMBASE_REG:
3615 case OP_STORER4_MEMBASE_REG:
3616 case OP_STORER8_MEMBASE_REG:
3617 case OP_STORE_MEMBASE_REG: {
3619 LLVMValueRef index, addr;
3621 gboolean sext = FALSE, zext = FALSE;
3622 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3624 if (!values [ins->inst_destbasereg])
3625 LLVM_FAILURE (ctx, "inst_destbasereg");
3627 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3629 if (ins->inst_offset % size != 0) {
3630 /* Unaligned store */
3631 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3632 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3634 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3635 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3637 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3641 case OP_STOREI1_MEMBASE_IMM:
3642 case OP_STOREI2_MEMBASE_IMM:
3643 case OP_STOREI4_MEMBASE_IMM:
3644 case OP_STOREI8_MEMBASE_IMM:
3645 case OP_STORE_MEMBASE_IMM: {
3647 LLVMValueRef index, addr;
3649 gboolean sext = FALSE, zext = FALSE;
3650 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3652 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3654 if (ins->inst_offset % size != 0) {
3655 /* Unaligned store */
3656 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3657 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3659 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3660 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3662 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3667 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3669 case OP_OUTARG_VTRETADDR:
3677 case OP_VOIDCALL_MEMBASE:
3678 case OP_CALL_MEMBASE:
3679 case OP_LCALL_MEMBASE:
3680 case OP_FCALL_MEMBASE:
3681 case OP_RCALL_MEMBASE:
3682 case OP_VCALL_MEMBASE:
3683 case OP_VOIDCALL_REG:
3688 case OP_VCALL_REG: {
3689 process_call (ctx, bb, &builder, ins);
3690 CHECK_FAILURE (ctx);
3695 LLVMValueRef indexes [2];
3697 LLVMValueRef got_entry_addr;
3700 * FIXME: Can't allocate from the cfg mempool since that is freed if
3701 * the LLVM compile fails.
3703 ji = g_new0 (MonoJumpInfo, 1);
3704 ji->type = (MonoJumpInfoType)ins->inst_i1;
3705 ji->data.target = ins->inst_p0;
3707 ji = mono_aot_patch_info_dup (ji);
3709 ji->next = cfg->patch_info;
3710 cfg->patch_info = ji;
3712 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3713 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3714 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3716 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3717 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3718 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3720 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3721 set_invariant_load_flag (values [ins->dreg]);
3724 case OP_NOT_REACHED:
3725 LLVMBuildUnreachable (builder);
3726 has_terminator = TRUE;
3727 g_assert (bb->block_num < cfg->max_block_num);
3728 ctx->unreachable [bb->block_num] = TRUE;
3729 /* Might have instructions after this */
3731 MonoInst *next = ins->next;
3733 * FIXME: If later code uses the regs defined by these instructions,
3734 * compilation will fail.
3736 MONO_DELETE_INS (bb, next);
3740 MonoInst *var = ins->inst_p0;
3742 values [ins->dreg] = addresses [var->dreg];
3746 LLVMValueRef args [1];
3748 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3749 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3753 LLVMValueRef args [1];
3755 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3756 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3760 LLVMValueRef args [1];
3763 /* This no longer seems to happen */
3765 * LLVM optimizes sqrt(nan) into undefined in
3766 * lib/Analysis/ConstantFolding.cpp
3767 * Also, sqrt(NegativeInfinity) is optimized into 0.
3769 LLVM_FAILURE (ctx, "sqrt");
3771 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3772 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3776 LLVMValueRef args [1];
3778 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3779 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3793 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3794 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3796 switch (ins->opcode) {
3799 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3803 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3807 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3811 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3814 g_assert_not_reached ();
3817 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3820 case OP_ATOMIC_EXCHANGE_I4:
3821 case OP_ATOMIC_EXCHANGE_I8: {
3822 LLVMValueRef args [2];
3825 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3826 t = LLVMInt32Type ();
3828 t = LLVMInt64Type ();
3830 g_assert (ins->inst_offset == 0);
3832 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3833 args [1] = convert (ctx, rhs, t);
3835 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3838 case OP_ATOMIC_ADD_I4:
3839 case OP_ATOMIC_ADD_I8: {
3840 LLVMValueRef args [2];
3843 if (ins->opcode == OP_ATOMIC_ADD_I4)
3844 t = LLVMInt32Type ();
3846 t = LLVMInt64Type ();
3848 g_assert (ins->inst_offset == 0);
3850 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3851 args [1] = convert (ctx, rhs, t);
3852 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3855 case OP_ATOMIC_CAS_I4:
3856 case OP_ATOMIC_CAS_I8: {
3857 LLVMValueRef args [3], val;
3860 if (ins->opcode == OP_ATOMIC_CAS_I4)
3861 t = LLVMInt32Type ();
3863 t = LLVMInt64Type ();
3865 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3867 args [1] = convert (ctx, values [ins->sreg3], t);
3869 args [2] = convert (ctx, values [ins->sreg2], t);
3870 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3871 /* cmpxchg returns a pair */
3872 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3875 case OP_MEMORY_BARRIER: {
3876 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3879 case OP_ATOMIC_LOAD_I1:
3880 case OP_ATOMIC_LOAD_I2:
3881 case OP_ATOMIC_LOAD_I4:
3882 case OP_ATOMIC_LOAD_I8:
3883 case OP_ATOMIC_LOAD_U1:
3884 case OP_ATOMIC_LOAD_U2:
3885 case OP_ATOMIC_LOAD_U4:
3886 case OP_ATOMIC_LOAD_U8:
3887 case OP_ATOMIC_LOAD_R4:
3888 case OP_ATOMIC_LOAD_R8: {
3889 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3892 gboolean sext, zext;
3894 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3895 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3896 LLVMValueRef index, addr;
3898 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3903 if (ins->inst_offset != 0) {
3904 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3905 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3910 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3912 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3915 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3917 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3920 case OP_ATOMIC_STORE_I1:
3921 case OP_ATOMIC_STORE_I2:
3922 case OP_ATOMIC_STORE_I4:
3923 case OP_ATOMIC_STORE_I8:
3924 case OP_ATOMIC_STORE_U1:
3925 case OP_ATOMIC_STORE_U2:
3926 case OP_ATOMIC_STORE_U4:
3927 case OP_ATOMIC_STORE_U8:
3928 case OP_ATOMIC_STORE_R4:
3929 case OP_ATOMIC_STORE_R8: {
3930 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3933 gboolean sext, zext;
3935 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3936 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3937 LLVMValueRef index, addr, value;
3939 if (!values [ins->inst_destbasereg])
3940 LLVM_FAILURE (ctx, "inst_destbasereg");
3942 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3944 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3945 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3946 value = convert (ctx, values [ins->sreg1], t);
3948 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3951 case OP_RELAXED_NOP: {
3952 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3953 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3960 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3962 // 257 == FS segment register
3963 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3965 // 256 == GS segment register
3966 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3969 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3970 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3971 /* See mono_amd64_emit_tls_get () */
3972 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3974 // 256 == GS segment register
3975 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3976 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3978 LLVM_FAILURE (ctx, "opcode tls-get");
3983 case OP_TLS_GET_REG: {
3984 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3985 /* See emit_tls_get_reg () */
3986 // 256 == GS segment register
3987 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3988 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3990 LLVM_FAILURE (ctx, "opcode tls-get");
3999 case OP_IADD_OVF_UN:
4001 case OP_ISUB_OVF_UN:
4003 case OP_IMUL_OVF_UN:
4004 #if SIZEOF_VOID_P == 8
4006 case OP_LADD_OVF_UN:
4008 case OP_LSUB_OVF_UN:
4010 case OP_LMUL_OVF_UN:
4013 LLVMValueRef args [2], val, ovf, func;
4015 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4016 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4017 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4019 val = LLVMBuildCall (builder, func, args, 2, "");
4020 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4021 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4022 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4023 CHECK_FAILURE (ctx);
4024 builder = ctx->builder;
4030 * We currently model them using arrays. Promotion to local vregs is
4031 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4032 * so we always have an entry in cfg->varinfo for them.
4033 * FIXME: Is this needed ?
4036 MonoClass *klass = ins->klass;
4037 LLVMValueRef args [5];
4041 LLVM_FAILURE (ctx, "!klass");
4045 if (!addresses [ins->dreg])
4046 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4047 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4048 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4049 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4051 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4052 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4053 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4056 case OP_DUMMY_VZERO:
4059 case OP_STOREV_MEMBASE:
4060 case OP_LOADV_MEMBASE:
4062 MonoClass *klass = ins->klass;
4063 LLVMValueRef src = NULL, dst, args [5];
4064 gboolean done = FALSE;
4068 LLVM_FAILURE (ctx, "!klass");
4072 if (mini_is_gsharedvt_klass (cfg, klass)) {
4074 LLVM_FAILURE (ctx, "gsharedvt");
4078 switch (ins->opcode) {
4079 case OP_STOREV_MEMBASE:
4080 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4081 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4082 /* Decomposed earlier */
4083 g_assert_not_reached ();
4086 if (!addresses [ins->sreg1]) {
4088 g_assert (values [ins->sreg1]);
4089 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));
4090 LLVMBuildStore (builder, values [ins->sreg1], dst);
4093 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4094 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4097 case OP_LOADV_MEMBASE:
4098 if (!addresses [ins->dreg])
4099 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4100 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4101 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4104 if (!addresses [ins->sreg1])
4105 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4106 if (!addresses [ins->dreg])
4107 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4108 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4109 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4112 g_assert_not_reached ();
4114 CHECK_FAILURE (ctx);
4121 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4122 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4124 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4125 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4126 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4129 case OP_LLVM_OUTARG_VT:
4130 if (!addresses [ins->sreg1]) {
4131 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4132 g_assert (values [ins->sreg1]);
4133 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4135 addresses [ins->dreg] = addresses [ins->sreg1];
4141 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4143 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4146 case OP_LOADX_MEMBASE: {
4147 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4150 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4151 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4154 case OP_STOREX_MEMBASE: {
4155 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4158 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4159 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4166 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4170 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4176 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4180 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4184 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4188 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4191 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4194 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4197 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4201 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4212 LLVMValueRef v = NULL;
4214 switch (ins->opcode) {
4219 t = LLVMVectorType (LLVMInt32Type (), 4);
4220 rt = LLVMVectorType (LLVMFloatType (), 4);
4226 t = LLVMVectorType (LLVMInt64Type (), 2);
4227 rt = LLVMVectorType (LLVMDoubleType (), 2);
4230 t = LLVMInt32Type ();
4231 rt = LLVMInt32Type ();
4232 g_assert_not_reached ();
4235 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4236 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4237 switch (ins->opcode) {
4240 v = LLVMBuildAnd (builder, lhs, rhs, "");
4244 v = LLVMBuildOr (builder, lhs, rhs, "");
4248 v = LLVMBuildXor (builder, lhs, rhs, "");
4252 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4255 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4279 case OP_PADDB_SAT_UN:
4280 case OP_PADDW_SAT_UN:
4281 case OP_PSUBB_SAT_UN:
4282 case OP_PSUBW_SAT_UN:
4290 case OP_PMULW_HIGH_UN: {
4291 LLVMValueRef args [2];
4296 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4303 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4307 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4315 case OP_EXTRACTX_U2:
4317 case OP_EXTRACT_U1: {
4319 gboolean zext = FALSE;
4321 t = simd_op_to_llvm_type (ins->opcode);
4323 switch (ins->opcode) {
4331 case OP_EXTRACTX_U2:
4336 t = LLVMInt32Type ();
4337 g_assert_not_reached ();
4340 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4341 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4343 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4352 case OP_EXPAND_R8: {
4353 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4354 LLVMValueRef mask [16], v;
4357 for (i = 0; i < 16; ++i)
4358 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4360 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4362 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4363 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4368 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4371 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4374 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4377 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4380 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4383 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4394 case OP_EXTRACT_MASK:
4401 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4403 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4409 LLVMValueRef args [3];
4413 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4415 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4420 /* This is only used for implementing shifts by non-immediate */
4421 values [ins->dreg] = lhs;
4432 LLVMValueRef args [3];
4435 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4437 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4448 case OP_PSHLQ_REG: {
4449 LLVMValueRef args [3];
4452 args [1] = values [ins->sreg2];
4454 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4461 case OP_PSHUFLEW_LOW:
4462 case OP_PSHUFLEW_HIGH: {
4464 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4465 int i, mask_size = 0;
4466 int imask = ins->inst_c0;
4468 /* Convert the x86 shuffle mask to LLVM's */
4469 switch (ins->opcode) {
4472 mask [0] = ((imask >> 0) & 3);
4473 mask [1] = ((imask >> 2) & 3);
4474 mask [2] = ((imask >> 4) & 3) + 4;
4475 mask [3] = ((imask >> 6) & 3) + 4;
4476 v1 = values [ins->sreg1];
4477 v2 = values [ins->sreg2];
4481 mask [0] = ((imask >> 0) & 1);
4482 mask [1] = ((imask >> 1) & 1) + 2;
4483 v1 = values [ins->sreg1];
4484 v2 = values [ins->sreg2];
4486 case OP_PSHUFLEW_LOW:
4488 mask [0] = ((imask >> 0) & 3);
4489 mask [1] = ((imask >> 2) & 3);
4490 mask [2] = ((imask >> 4) & 3);
4491 mask [3] = ((imask >> 6) & 3);
4496 v1 = values [ins->sreg1];
4497 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4499 case OP_PSHUFLEW_HIGH:
4505 mask [4] = 4 + ((imask >> 0) & 3);
4506 mask [5] = 4 + ((imask >> 2) & 3);
4507 mask [6] = 4 + ((imask >> 4) & 3);
4508 mask [7] = 4 + ((imask >> 6) & 3);
4509 v1 = values [ins->sreg1];
4510 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4514 mask [0] = ((imask >> 0) & 3);
4515 mask [1] = ((imask >> 2) & 3);
4516 mask [2] = ((imask >> 4) & 3);
4517 mask [3] = ((imask >> 6) & 3);
4518 v1 = values [ins->sreg1];
4519 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4522 g_assert_not_reached ();
4524 for (i = 0; i < mask_size; ++i)
4525 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4527 values [ins->dreg] =
4528 LLVMBuildShuffleVector (builder, v1, v2,
4529 LLVMConstVector (mask_values, mask_size), dname);
4533 case OP_UNPACK_LOWB:
4534 case OP_UNPACK_LOWW:
4535 case OP_UNPACK_LOWD:
4536 case OP_UNPACK_LOWQ:
4537 case OP_UNPACK_LOWPS:
4538 case OP_UNPACK_LOWPD:
4539 case OP_UNPACK_HIGHB:
4540 case OP_UNPACK_HIGHW:
4541 case OP_UNPACK_HIGHD:
4542 case OP_UNPACK_HIGHQ:
4543 case OP_UNPACK_HIGHPS:
4544 case OP_UNPACK_HIGHPD: {
4546 LLVMValueRef mask_values [16];
4547 int i, mask_size = 0;
4548 gboolean low = FALSE;
4550 switch (ins->opcode) {
4551 case OP_UNPACK_LOWB:
4555 case OP_UNPACK_LOWW:
4559 case OP_UNPACK_LOWD:
4560 case OP_UNPACK_LOWPS:
4564 case OP_UNPACK_LOWQ:
4565 case OP_UNPACK_LOWPD:
4569 case OP_UNPACK_HIGHB:
4572 case OP_UNPACK_HIGHW:
4575 case OP_UNPACK_HIGHD:
4576 case OP_UNPACK_HIGHPS:
4579 case OP_UNPACK_HIGHQ:
4580 case OP_UNPACK_HIGHPD:
4584 g_assert_not_reached ();
4588 for (i = 0; i < (mask_size / 2); ++i) {
4590 mask [(i * 2) + 1] = mask_size + i;
4593 for (i = 0; i < (mask_size / 2); ++i) {
4594 mask [(i * 2)] = (mask_size / 2) + i;
4595 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4599 for (i = 0; i < mask_size; ++i)
4600 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4602 values [ins->dreg] =
4603 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4604 LLVMConstVector (mask_values, mask_size), dname);
4609 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4610 LLVMValueRef v, val;
4612 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4613 val = LLVMConstNull (t);
4614 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4615 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4617 values [ins->dreg] = val;
4621 case OP_DUPPS_HIGH: {
4622 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4623 LLVMValueRef v1, v2, val;
4626 if (ins->opcode == OP_DUPPS_LOW) {
4627 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4628 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4630 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4631 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4633 val = LLVMConstNull (t);
4634 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4635 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4636 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4637 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4639 values [ins->dreg] = val;
4649 * EXCEPTION HANDLING
4651 case OP_IMPLICIT_EXCEPTION:
4652 /* This marks a place where an implicit exception can happen */
4653 if (bb->region != -1)
4654 LLVM_FAILURE (ctx, "implicit-exception");
4658 MonoMethodSignature *throw_sig;
4659 LLVMValueRef callee, arg;
4660 gboolean rethrow = (ins->opcode == OP_RETHROW);
4661 const char *icall_name;
4663 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4664 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4667 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4668 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4669 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4670 if (cfg->compile_aot) {
4671 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4673 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4677 * LLVM doesn't push the exception argument, so we need a different
4680 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4682 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4686 mono_memory_barrier ();
4688 ctx->lmodule->rethrow = callee;
4690 ctx->lmodule->throw = callee;
4692 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4693 emit_call (ctx, bb, &builder, callee, &arg, 1);
4696 case OP_CALL_HANDLER: {
4698 * We don't 'call' handlers, but instead simply branch to them.
4699 * The code generated by ENDFINALLY will branch back to us.
4701 LLVMBasicBlockRef noex_bb;
4703 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4705 bb_list = info->call_handler_return_bbs;
4708 * Set the indicator variable for the finally clause.
4710 lhs = info->finally_ind;
4712 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4714 /* Branch to the finally clause */
4715 LLVMBuildBr (builder, info->call_handler_target_bb);
4717 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4718 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4720 builder = ctx->builder = create_builder (ctx);
4721 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4723 bblocks [bb->block_num].end_bblock = noex_bb;
4726 case OP_START_HANDLER: {
4729 case OP_ENDFINALLY: {
4730 LLVMBasicBlockRef resume_bb;
4731 MonoBasicBlock *handler_bb;
4732 LLVMValueRef val, switch_ins, callee;
4736 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4737 g_assert (handler_bb);
4738 info = &bblocks [handler_bb->block_num];
4739 lhs = info->finally_ind;
4742 bb_list = info->call_handler_return_bbs;
4744 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4746 /* Load the finally variable */
4747 val = LLVMBuildLoad (builder, lhs, "");
4749 /* Reset the variable */
4750 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4752 /* Branch to either resume_bb, or to the bblocks in bb_list */
4753 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4755 * The other targets are added at the end to handle OP_CALL_HANDLER
4756 * opcodes processed later.
4758 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4760 builder = ctx->builder = create_builder (ctx);
4761 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4763 if (ctx->cfg->compile_aot) {
4764 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4766 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4768 LLVMBuildCall (builder, callee, NULL, 0, "");
4770 LLVMBuildUnreachable (builder);
4771 has_terminator = TRUE;
4777 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4778 LLVM_FAILURE (ctx, reason);
4783 /* Convert the value to the type required by phi nodes */
4784 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4785 if (!values [ins->dreg])
4787 values [ins->dreg] = addresses [ins->dreg];
4789 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4792 /* Add stores for volatile variables */
4793 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4794 emit_volatile_store (ctx, ins->dreg);
4797 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4798 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4800 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4801 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4802 LLVMBuildRetVoid (builder);
4805 if (bb == cfg->bb_entry)
4806 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4815 * mono_llvm_check_method_supported:
4817 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4818 * compiling a method twice.
4821 mono_llvm_check_method_supported (MonoCompile *cfg)
4825 if (cfg->method->save_lmf) {
4826 cfg->exception_message = g_strdup ("lmf");
4827 cfg->disable_llvm = TRUE;
4829 if (cfg->disable_llvm)
4833 * Nested clauses where one of the clauses is a finally clause is
4834 * not supported, because LLVM can't figure out the control flow,
4835 * probably because we resume exception handling by calling our
4836 * own function instead of using the 'resume' llvm instruction.
4838 for (i = 0; i < cfg->header->num_clauses; ++i) {
4839 for (j = 0; j < cfg->header->num_clauses; ++j) {
4840 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4841 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4843 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4844 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4845 cfg->exception_message = g_strdup ("nested clauses");
4846 cfg->disable_llvm = TRUE;
4851 if (cfg->disable_llvm)
4855 if (cfg->method->dynamic) {
4856 cfg->exception_message = g_strdup ("dynamic.");
4857 cfg->disable_llvm = TRUE;
4859 if (cfg->disable_llvm)
4864 * mono_llvm_emit_method:
4866 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4869 mono_llvm_emit_method (MonoCompile *cfg)
4872 MonoMethodSignature *sig;
4874 LLVMTypeRef method_type;
4875 LLVMValueRef method = NULL;
4877 LLVMValueRef *values;
4878 int i, max_block_num, bb_index;
4879 gboolean last = FALSE;
4880 GPtrArray *phi_values;
4881 LLVMCallInfo *linfo;
4883 LLVMModuleRef module;
4885 GPtrArray *bblock_list;
4886 MonoMethodHeader *header;
4887 MonoExceptionClause *clause;
4891 /* The code below might acquire the loader lock, so use it for global locking */
4892 mono_loader_lock ();
4894 /* Used to communicate with the callbacks */
4895 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4897 ctx = g_new0 (EmitContext, 1);
4899 ctx->mempool = cfg->mempool;
4902 * This maps vregs to the LLVM instruction defining them
4904 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4906 * This maps vregs for volatile variables to the LLVM instruction defining their
4909 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4910 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4911 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4912 phi_values = g_ptr_array_sized_new (256);
4914 * This signals whenever the vreg was defined by a phi node with no input vars
4915 * (i.e. all its input bblocks end with NOT_REACHABLE).
4917 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4918 /* Whenever the bblock is unreachable */
4919 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4921 bblock_list = g_ptr_array_sized_new (256);
4923 ctx->values = values;
4924 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4925 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4927 if (cfg->compile_aot) {
4928 ctx->lmodule = &aot_module;
4929 method_name = mono_aot_get_method_name (cfg);
4930 cfg->llvm_method_name = g_strdup (method_name);
4932 init_jit_module (cfg->domain);
4933 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4934 method_name = mono_method_full_name (cfg->method, TRUE);
4937 module = ctx->module = ctx->lmodule->module;
4940 LLVM_FAILURE (ctx, "gsharedvt");
4944 static int count = 0;
4947 if (g_getenv ("LLVM_COUNT")) {
4948 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4949 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4953 if (count > atoi (g_getenv ("LLVM_COUNT")))
4954 LLVM_FAILURE (ctx, "");
4959 sig = mono_method_signature (cfg->method);
4962 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4964 CHECK_FAILURE (ctx);
4967 linfo->rgctx_arg = TRUE;
4968 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4969 CHECK_FAILURE (ctx);
4972 * This maps parameter indexes in the original signature to the indexes in
4973 * the LLVM signature.
4975 ctx->pindexes = sinfo.pindexes;
4977 method = LLVMAddFunction (module, method_name, method_type);
4978 ctx->lmethod = method;
4980 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4981 LLVMSetLinkage (method, LLVMPrivateLinkage);
4983 LLVMAddFunctionAttr (method, LLVMUWTable);
4985 if (cfg->compile_aot) {
4986 LLVMSetLinkage (method, LLVMInternalLinkage);
4987 if (ctx->lmodule->external_symbols) {
4988 LLVMSetLinkage (method, LLVMExternalLinkage);
4989 LLVMSetVisibility (method, LLVMHiddenVisibility);
4992 LLVMSetLinkage (method, LLVMPrivateLinkage);
4995 if (cfg->method->save_lmf)
4996 LLVM_FAILURE (ctx, "lmf");
4998 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4999 LLVM_FAILURE (ctx, "pinvoke signature");
5001 header = cfg->header;
5002 for (i = 0; i < header->num_clauses; ++i) {
5003 clause = &header->clauses [i];
5004 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5005 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5007 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5008 /* We can't handle inlined methods with clauses */
5009 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5011 if (linfo->rgctx_arg) {
5012 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5014 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5015 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5016 * CC_X86_64_Mono in X86CallingConv.td.
5018 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5019 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5021 if (cfg->vret_addr) {
5022 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5023 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5026 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5027 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5030 names = g_new (char *, sig->param_count);
5031 mono_method_get_param_names (cfg->method, (const char **) names);
5033 for (i = 0; i < sig->param_count; ++i) {
5036 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5037 if (names [i] && names [i][0] != '\0')
5038 name = g_strdup_printf ("arg_%s", names [i]);
5040 name = g_strdup_printf ("arg_%d", i);
5041 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5043 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5044 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5048 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5049 ctx->minfo = mono_debug_lookup_method (cfg->method);
5050 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5054 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5055 max_block_num = MAX (max_block_num, bb->block_num);
5056 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5058 /* Add branches between non-consecutive bblocks */
5059 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5060 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5061 bb->next_bb != bb->last_ins->inst_false_bb) {
5063 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5064 inst->opcode = OP_BR;
5065 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5066 mono_bblock_add_inst (bb, inst);
5071 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5072 * was later optimized away, so clear these flags, and add them back for the still
5073 * present OP_LDADDR instructions.
5075 for (i = 0; i < cfg->next_vreg; ++i) {
5078 ins = get_vreg_to_inst (cfg, i);
5079 if (ins && ins != cfg->rgctx_var)
5080 ins->flags &= ~MONO_INST_INDIRECT;
5084 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5086 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5088 LLVMBuilderRef builder;
5090 char dname_buf[128];
5092 builder = create_builder (ctx);
5094 for (ins = bb->code; ins; ins = ins->next) {
5095 switch (ins->opcode) {
5100 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5102 CHECK_FAILURE (ctx);
5104 if (ins->opcode == OP_VPHI) {
5105 /* Treat valuetype PHI nodes as operating on the address itself */
5106 g_assert (ins->klass);
5107 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5111 * Have to precreate these, as they can be referenced by
5112 * earlier instructions.
5114 sprintf (dname_buf, "t%d", ins->dreg);
5116 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5118 if (ins->opcode == OP_VPHI)
5119 ctx->addresses [ins->dreg] = values [ins->dreg];
5121 g_ptr_array_add (phi_values, values [ins->dreg]);
5124 * Set the expected type of the incoming arguments since these have
5125 * to have the same type.
5127 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5128 int sreg1 = ins->inst_phi_args [i + 1];
5131 ctx->vreg_types [sreg1] = phi_type;
5136 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5145 * Create an ordering for bblocks, use the depth first order first, then
5146 * put the exception handling bblocks last.
5148 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5149 bb = cfg->bblocks [bb_index];
5150 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5151 g_ptr_array_add (bblock_list, bb);
5152 bblocks [bb->block_num].added = TRUE;
5156 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5157 if (!bblocks [bb->block_num].added)
5158 g_ptr_array_add (bblock_list, bb);
5162 * Second pass: generate code.
5164 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5165 bb = g_ptr_array_index (bblock_list, bb_index);
5167 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5170 process_bb (ctx, bb);
5171 CHECK_FAILURE (ctx);
5174 /* Add incoming phi values */
5175 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5176 GSList *l, *ins_list;
5178 ins_list = bblocks [bb->block_num].phi_nodes;
5180 for (l = ins_list; l; l = l->next) {
5181 PhiNode *node = l->data;
5182 MonoInst *phi = node->phi;
5183 int sreg1 = node->sreg;
5184 LLVMBasicBlockRef in_bb;
5189 in_bb = get_end_bb (ctx, node->in_bb);
5191 if (ctx->unreachable [node->in_bb->block_num])
5194 if (!values [sreg1])
5195 /* Can happen with values in EH clauses */
5196 LLVM_FAILURE (ctx, "incoming phi sreg1");
5198 if (phi->opcode == OP_VPHI) {
5199 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5200 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5202 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5204 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5205 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5206 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5211 /* Create the SWITCH statements for ENDFINALLY instructions */
5212 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5213 BBInfo *info = &bblocks [bb->block_num];
5215 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5216 LLVMValueRef switch_ins = l->data;
5217 GSList *bb_list = info->call_handler_return_bbs;
5219 for (i = 0; i < g_slist_length (bb_list); ++i)
5220 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5224 if (cfg->verbose_level > 1)
5225 mono_llvm_dump_value (method);
5227 if (cfg->compile_aot)
5228 mark_as_used (ctx->lmodule, method);
5230 if (cfg->compile_aot) {
5231 LLVMValueRef md_args [16];
5232 LLVMValueRef md_node;
5235 method_index = mono_aot_get_method_index (cfg->orig_method);
5236 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5237 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5238 md_node = LLVMMDNode (md_args, 2);
5239 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5240 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5243 if (cfg->compile_aot) {
5244 /* Don't generate native code, keep the LLVM IR */
5245 if (cfg->compile_aot && cfg->verbose_level)
5246 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5248 //LLVMVerifyFunction(method, 0);
5250 //LLVMVerifyFunction(method, 0);
5251 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5253 if (cfg->verbose_level > 1)
5254 mono_llvm_dump_value (method);
5256 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5258 /* Set by emit_cb */
5259 g_assert (cfg->code_len);
5261 /* FIXME: Free the LLVM IL for the function */
5264 if (ctx->lmodule->method_to_lmethod)
5265 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5272 /* Need to add unused phi nodes as they can be referenced by other values */
5273 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5274 LLVMBuilderRef builder;
5276 builder = create_builder (ctx);
5277 LLVMPositionBuilderAtEnd (builder, phi_bb);
5279 for (i = 0; i < phi_values->len; ++i) {
5280 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5281 if (LLVMGetInstructionParent (v) == NULL)
5282 LLVMInsertIntoBuilder (builder, v);
5285 LLVMDeleteFunction (method);
5290 g_free (ctx->addresses);
5291 g_free (ctx->vreg_types);
5292 g_free (ctx->vreg_cli_types);
5293 g_free (ctx->pindexes);
5294 g_free (ctx->is_dead);
5295 g_free (ctx->unreachable);
5296 g_ptr_array_free (phi_values, TRUE);
5297 g_free (ctx->bblocks);
5298 g_hash_table_destroy (ctx->region_to_handler);
5299 g_hash_table_destroy (ctx->clause_to_handler);
5300 g_free (method_name);
5301 g_ptr_array_free (bblock_list, TRUE);
5303 for (l = ctx->builders; l; l = l->next) {
5304 LLVMBuilderRef builder = l->data;
5305 LLVMDisposeBuilder (builder);
5310 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5312 mono_loader_unlock ();
5316 * mono_llvm_emit_call:
5318 * Same as mono_arch_emit_call () for LLVM.
5321 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5324 MonoMethodSignature *sig;
5325 int i, n, stack_size;
5330 sig = call->signature;
5331 n = sig->param_count + sig->hasthis;
5333 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5335 if (cfg->disable_llvm)
5338 if (sig->call_convention == MONO_CALL_VARARG) {
5339 cfg->exception_message = g_strdup ("varargs");
5340 cfg->disable_llvm = TRUE;
5343 for (i = 0; i < n; ++i) {
5346 ainfo = call->cinfo->args + i;
5348 in = call->args [i];
5350 /* Simply remember the arguments */
5351 switch (ainfo->storage) {
5353 case LLVMArgInFPReg: {
5354 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5357 opcode = mono_type_to_regmove (cfg, t);
5358 if (opcode == OP_FMOVE) {
5359 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5360 ins->dreg = mono_alloc_freg (cfg);
5361 } else if (opcode == OP_LMOVE) {
5362 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5363 ins->dreg = mono_alloc_lreg (cfg);
5365 MONO_INST_NEW (cfg, ins, OP_MOVE);
5366 ins->dreg = mono_alloc_ireg (cfg);
5368 ins->sreg1 = in->dreg;
5371 case LLVMArgVtypeByVal:
5372 case LLVMArgVtypeInReg:
5373 case LLVMArgAsIArgs:
5374 case LLVMArgAsFpArgs:
5375 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5376 ins->dreg = mono_alloc_ireg (cfg);
5377 ins->sreg1 = in->dreg;
5378 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5381 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5382 cfg->exception_message = g_strdup ("ainfo->storage");
5383 cfg->disable_llvm = TRUE;
5387 if (!cfg->disable_llvm) {
5388 MONO_ADD_INS (cfg->cbb, ins);
5389 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5394 static unsigned char*
5395 alloc_cb (LLVMValueRef function, int size)
5399 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5403 return mono_domain_code_reserve (cfg->domain, size);
5405 return mono_domain_code_reserve (mono_domain_get (), size);
5410 emitted_cb (LLVMValueRef function, void *start, void *end)
5414 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5416 cfg->code_len = (guint8*)end - (guint8*)start;
5420 exception_cb (void *data)
5423 MonoJitExceptionInfo *ei;
5424 guint32 ei_len, i, j, nested_len, nindex;
5425 gpointer *type_info;
5426 int this_reg, this_offset;
5428 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5432 * data points to a DWARF FDE structure, convert it to our unwind format and
5434 * An alternative would be to save it directly, and modify our unwinder to work
5437 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);
5438 if (cfg->verbose_level > 1)
5439 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5441 /* Count nested clauses */
5443 for (i = 0; i < ei_len; ++i) {
5444 for (j = 0; j < ei_len; ++j) {
5445 gint32 cindex1 = *(gint32*)type_info [i];
5446 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5447 gint32 cindex2 = *(gint32*)type_info [j];
5448 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5450 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5456 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5457 cfg->llvm_ex_info_len = ei_len + nested_len;
5458 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5459 /* Fill the rest of the information from the type info */
5460 for (i = 0; i < ei_len; ++i) {
5461 gint32 clause_index = *(gint32*)type_info [i];
5462 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5464 cfg->llvm_ex_info [i].flags = clause->flags;
5465 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5466 cfg->llvm_ex_info [i].clause_index = clause_index;
5470 * For nested clauses, the LLVM produced exception info associates the try interval with
5471 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5472 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5473 * and everything else from the nested clause.
5476 for (i = 0; i < ei_len; ++i) {
5477 for (j = 0; j < ei_len; ++j) {
5478 gint32 cindex1 = *(gint32*)type_info [i];
5479 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5480 gint32 cindex2 = *(gint32*)type_info [j];
5481 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5483 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5484 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5485 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5486 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5487 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5488 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5493 g_assert (nindex == ei_len + nested_len);
5494 cfg->llvm_this_reg = this_reg;
5495 cfg->llvm_this_offset = this_offset;
5497 /* type_info [i] is cfg mempool allocated, no need to free it */
5504 dlsym_cb (const char *name, void **symbol)
5510 if (!strcmp (name, "__bzero")) {
5511 *symbol = (void*)bzero;
5513 current = mono_dl_open (NULL, 0, NULL);
5516 err = mono_dl_symbol (current, name, symbol);
5518 mono_dl_close (current);
5520 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5521 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5527 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5529 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5533 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5535 LLVMTypeRef param_types [4];
5537 param_types [0] = param_type1;
5538 param_types [1] = param_type2;
5540 AddFunc (module, name, ret_type, param_types, 2);
5544 add_intrinsics (LLVMModuleRef module)
5546 /* Emit declarations of instrinsics */
5548 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5549 * type doesn't seem to do any locking.
5552 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5554 memset_param_count = 5;
5555 memset_func_name = "llvm.memset.p0i8.i32";
5557 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5561 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5563 memcpy_param_count = 5;
5564 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5566 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5570 LLVMTypeRef params [] = { LLVMDoubleType () };
5572 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5573 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5574 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5576 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5577 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5581 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5582 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5583 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5585 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5586 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5587 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5588 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5589 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5590 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5591 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5595 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5596 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5597 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5599 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5600 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5601 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5602 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5603 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5604 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5609 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5611 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5614 /* SSE intrinsics */
5615 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5617 LLVMTypeRef ret_type, arg_types [16];
5620 ret_type = type_to_simd_type (MONO_TYPE_I4);
5621 arg_types [0] = ret_type;
5622 arg_types [1] = ret_type;
5623 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5624 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5626 ret_type = type_to_simd_type (MONO_TYPE_I2);
5627 arg_types [0] = ret_type;
5628 arg_types [1] = ret_type;
5629 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5630 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5631 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5633 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5640 ret_type = type_to_simd_type (MONO_TYPE_I1);
5641 arg_types [0] = ret_type;
5642 arg_types [1] = ret_type;
5643 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5644 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5645 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5647 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5648 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5649 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5651 ret_type = type_to_simd_type (MONO_TYPE_R8);
5652 arg_types [0] = ret_type;
5653 arg_types [1] = ret_type;
5654 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5655 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5656 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5657 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5658 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5660 ret_type = type_to_simd_type (MONO_TYPE_R4);
5661 arg_types [0] = ret_type;
5662 arg_types [1] = ret_type;
5663 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5664 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5665 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5666 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5667 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5670 ret_type = type_to_simd_type (MONO_TYPE_I1);
5671 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5672 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5673 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5674 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5675 ret_type = type_to_simd_type (MONO_TYPE_I2);
5676 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5677 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5678 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5679 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5682 ret_type = type_to_simd_type (MONO_TYPE_R8);
5683 arg_types [0] = ret_type;
5684 arg_types [1] = ret_type;
5685 arg_types [2] = LLVMInt8Type ();
5686 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5687 ret_type = type_to_simd_type (MONO_TYPE_R4);
5688 arg_types [0] = ret_type;
5689 arg_types [1] = ret_type;
5690 arg_types [2] = LLVMInt8Type ();
5691 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5693 /* Conversion ops */
5694 ret_type = type_to_simd_type (MONO_TYPE_R8);
5695 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5696 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5697 ret_type = type_to_simd_type (MONO_TYPE_R4);
5698 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5699 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5700 ret_type = type_to_simd_type (MONO_TYPE_I4);
5701 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5702 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5703 ret_type = type_to_simd_type (MONO_TYPE_I4);
5704 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5705 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5706 ret_type = type_to_simd_type (MONO_TYPE_R4);
5707 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5708 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5709 ret_type = type_to_simd_type (MONO_TYPE_R8);
5710 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5711 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5713 ret_type = type_to_simd_type (MONO_TYPE_I4);
5714 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5715 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5716 ret_type = type_to_simd_type (MONO_TYPE_I4);
5717 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5718 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5721 ret_type = type_to_simd_type (MONO_TYPE_R8);
5722 arg_types [0] = ret_type;
5723 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5724 ret_type = type_to_simd_type (MONO_TYPE_R4);
5725 arg_types [0] = ret_type;
5726 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5727 ret_type = type_to_simd_type (MONO_TYPE_R4);
5728 arg_types [0] = ret_type;
5729 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5730 ret_type = type_to_simd_type (MONO_TYPE_R4);
5731 arg_types [0] = ret_type;
5732 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5735 ret_type = type_to_simd_type (MONO_TYPE_I2);
5736 arg_types [0] = ret_type;
5737 arg_types [1] = LLVMInt32Type ();
5738 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5739 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5740 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5741 ret_type = type_to_simd_type (MONO_TYPE_I4);
5742 arg_types [0] = ret_type;
5743 arg_types [1] = LLVMInt32Type ();
5744 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5745 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5746 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5747 ret_type = type_to_simd_type (MONO_TYPE_I8);
5748 arg_types [0] = ret_type;
5749 arg_types [1] = LLVMInt32Type ();
5750 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5751 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5754 ret_type = LLVMInt32Type ();
5755 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5756 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5759 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5762 /* Load/Store intrinsics */
5764 LLVMTypeRef arg_types [5];
5768 for (i = 1; i <= 8; i *= 2) {
5769 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5770 arg_types [1] = LLVMInt32Type ();
5771 arg_types [2] = LLVMInt1Type ();
5772 arg_types [3] = LLVMInt32Type ();
5773 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5774 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5776 arg_types [0] = LLVMIntType (i * 8);
5777 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5778 arg_types [2] = LLVMInt32Type ();
5779 arg_types [3] = LLVMInt1Type ();
5780 arg_types [4] = LLVMInt32Type ();
5781 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5782 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5788 add_types (MonoLLVMModule *lmodule)
5790 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5794 mono_llvm_init (void)
5796 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5800 init_jit_module (MonoDomain *domain)
5802 MonoJitICallInfo *info;
5803 MonoJitDomainInfo *dinfo;
5804 MonoLLVMModule *module;
5807 dinfo = domain_jit_info (domain);
5808 if (dinfo->llvm_module)
5811 mono_loader_lock ();
5813 if (dinfo->llvm_module) {
5814 mono_loader_unlock ();
5818 module = g_new0 (MonoLLVMModule, 1);
5820 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5821 module->module = LLVMModuleCreateWithName (name);
5823 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5825 add_intrinsics (module->module);
5828 module->llvm_types = g_hash_table_new (NULL, NULL);
5830 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5832 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5834 mono_memory_barrier ();
5836 dinfo->llvm_module = module;
5838 mono_loader_unlock ();
5842 mono_llvm_cleanup (void)
5844 if (aot_module.module)
5845 LLVMDisposeModule (aot_module.module);
5847 LLVMContextDispose (LLVMGetGlobalContext ());
5851 mono_llvm_free_domain_info (MonoDomain *domain)
5853 MonoJitDomainInfo *info = domain_jit_info (domain);
5854 MonoLLVMModule *module = info->llvm_module;
5860 if (module->llvm_types)
5861 g_hash_table_destroy (module->llvm_types);
5863 mono_llvm_dispose_ee (module->mono_ee);
5865 if (module->bb_names) {
5866 for (i = 0; i < module->bb_names_len; ++i)
5867 g_free (module->bb_names [i]);
5868 g_free (module->bb_names);
5870 //LLVMDisposeModule (module->module);
5874 info->llvm_module = NULL;
5878 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link)
5880 MonoLLVMModule *lmodule = &aot_module;
5882 /* Delete previous module */
5883 if (lmodule->plt_entries)
5884 g_hash_table_destroy (lmodule->plt_entries);
5885 if (lmodule->module)
5886 LLVMDisposeModule (lmodule->module);
5888 memset (lmodule, 0, sizeof (aot_module));
5890 lmodule->module = LLVMModuleCreateWithName ("aot");
5891 lmodule->assembly = assembly;
5892 lmodule->global_prefix = g_strdup (global_prefix);
5893 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
5894 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
5895 lmodule->external_symbols = TRUE;
5896 lmodule->emit_dwarf = emit_dwarf;
5897 lmodule->static_link = static_link;
5898 /* The first few entries are reserved */
5899 lmodule->max_got_offset = 16;
5901 add_intrinsics (lmodule->module);
5902 add_types (lmodule);
5906 * We couldn't compute the type of the LLVM global representing the got because
5907 * its size is only known after all the methods have been emitted. So create
5908 * a dummy variable, and replace all uses it with the real got variable when
5909 * its size is known in mono_llvm_emit_aot_module ().
5912 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
5914 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
5915 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
5918 /* Add a dummy personality function */
5920 LLVMBasicBlockRef lbb;
5921 LLVMBuilderRef lbuilder;
5922 LLVMValueRef personality;
5924 personality = LLVMAddFunction (lmodule, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5925 LLVMSetLinkage (personality, LLVMInternalLinkage);
5926 lbb = LLVMAppendBasicBlock (personality, "BB0");
5927 lbuilder = LLVMCreateBuilder ();
5928 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5929 LLVMBuildRetVoid (lbuilder);
5930 mark_as_used (lmodule, personality);
5933 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
5934 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5935 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
5936 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
5940 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
5943 LLVMValueRef res, *vals;
5945 vals = g_new0 (LLVMValueRef, nvalues);
5946 for (i = 0; i < nvalues; ++i)
5947 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
5948 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
5954 * mono_llvm_emit_aot_file_info:
5956 * Emit the MonoAotFileInfo structure.
5957 * Same as emit_aot_file_info () in aot-compiler.c.
5960 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
5962 MonoLLVMModule *lmodule = &aot_module;
5964 /* Save these for later */
5965 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
5966 lmodule->has_jitted_code = has_jitted_code;
5970 * mono_llvm_emit_aot_data:
5972 * Emit the binary data DATA pointed to by symbol SYMBOL.
5975 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
5977 MonoLLVMModule *lmodule = &aot_module;
5981 type = LLVMArrayType (LLVMInt8Type (), data_len);
5982 d = LLVMAddGlobal (lmodule->module, type, symbol);
5983 LLVMSetVisibility (d, LLVMHiddenVisibility);
5984 LLVMSetLinkage (d, LLVMInternalLinkage);
5985 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
5986 mono_llvm_set_is_constant (d);
5989 /* Add a reference to a global defined in JITted code */
5991 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
5996 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
5997 v = LLVMAddGlobal (lmodule->module, type, s);
6003 emit_aot_file_info (MonoLLVMModule *lmodule)
6005 LLVMTypeRef file_info_type;
6006 LLVMTypeRef *eltypes, eltype;
6007 LLVMValueRef info_var;
6008 LLVMValueRef *fields;
6009 int i, nfields, tindex;
6010 MonoAotFileInfo *info;
6012 info = &lmodule->aot_info;
6014 /* Create an LLVM type to represent MonoAotFileInfo */
6016 eltypes = g_new (LLVMTypeRef, nfields);
6018 eltypes [tindex ++] = LLVMInt32Type ();
6019 eltypes [tindex ++] = LLVMInt32Type ();
6021 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6022 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
6024 for (i = 0; i < 13; ++i)
6025 eltypes [tindex ++] = LLVMInt32Type ();
6027 for (i = 0; i < 4; ++i)
6028 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6029 g_assert (tindex == nfields);
6030 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6031 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6033 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
6034 if (lmodule->static_link) {
6035 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
6036 LLVMSetLinkage (info_var, LLVMInternalLinkage);
6038 fields = g_new (LLVMValueRef, nfields);
6040 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6041 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6045 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6046 * for symbols defined in the .s file emitted by the aot compiler.
6048 eltype = eltypes [tindex];
6049 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
6050 fields [tindex ++] = lmodule->got_var;
6051 /* llc defines this directly */
6052 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
6053 if (TRUE || lmodule->has_jitted_code) {
6054 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
6055 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
6056 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
6058 fields [tindex ++] = LLVMConstNull (eltype);
6059 fields [tindex ++] = LLVMConstNull (eltype);
6060 fields [tindex ++] = LLVMConstNull (eltype);
6062 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
6063 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
6064 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
6065 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
6066 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
6067 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
6068 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
6069 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
6070 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
6071 /* Not needed (mem_end) */
6072 fields [tindex ++] = LLVMConstNull (eltype);
6073 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
6074 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
6075 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
6076 if (info->trampoline_size [0]) {
6077 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
6078 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
6079 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
6080 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
6082 fields [tindex ++] = LLVMConstNull (eltype);
6083 fields [tindex ++] = LLVMConstNull (eltype);
6084 fields [tindex ++] = LLVMConstNull (eltype);
6085 fields [tindex ++] = LLVMConstNull (eltype);
6087 if (lmodule->static_link)
6088 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
6090 fields [tindex ++] = LLVMConstNull (eltype);
6091 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
6092 if (TRUE || lmodule->has_jitted_code) {
6093 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
6094 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
6095 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
6096 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
6097 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
6098 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
6100 fields [tindex ++] = LLVMConstNull (eltype);
6101 fields [tindex ++] = LLVMConstNull (eltype);
6102 fields [tindex ++] = LLVMConstNull (eltype);
6103 fields [tindex ++] = LLVMConstNull (eltype);
6104 fields [tindex ++] = LLVMConstNull (eltype);
6105 fields [tindex ++] = LLVMConstNull (eltype);
6109 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6110 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6111 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6112 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6113 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6114 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6115 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6116 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6117 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6118 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6119 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6120 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6121 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6123 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6124 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6125 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6126 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6127 g_assert (tindex == nfields);
6129 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6131 if (lmodule->static_link) {
6135 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
6136 /* Get rid of characters which cannot occur in symbols */
6138 for (p = s; *p; ++p) {
6139 if (!(isalnum (*p) || *p == '_'))
6142 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
6144 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
6145 LLVMSetLinkage (var, LLVMExternalLinkage);
6150 * Emit the aot module into the LLVM bitcode file FILENAME.
6153 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6155 LLVMTypeRef got_type;
6156 LLVMValueRef real_got;
6157 MonoLLVMModule *module = &aot_module;
6160 * Create the real got variable and replace all uses of the dummy variable with
6163 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6164 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6165 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6166 if (module->external_symbols) {
6167 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6168 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6170 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6172 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6174 mark_as_used (&aot_module, real_got);
6176 /* Delete the dummy got so it doesn't become a global */
6177 LLVMDeleteGlobal (aot_module.got_var);
6178 aot_module.got_var = real_got;
6180 emit_llvm_used (&aot_module);
6181 emit_dbg_info (&aot_module, filename, cu_name);
6182 emit_aot_file_info (&aot_module);
6184 /* Replace PLT entries for directly callable methods with the methods themselves */
6186 GHashTableIter iter;
6188 LLVMValueRef callee;
6190 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6191 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6192 if (mono_aot_is_direct_callable (ji)) {
6193 LLVMValueRef lmethod;
6195 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6196 /* The types might not match because the caller might pass an rgctx */
6197 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6198 mono_llvm_replace_uses_of (callee, lmethod);
6199 mono_aot_mark_unused_llvm_plt_entry (ji);
6209 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6210 g_assert_not_reached ();
6215 LLVMWriteBitcodeToFile (aot_module.module, filename);
6220 md_string (const char *s)
6222 return LLVMMDString (s, strlen (s));
6225 /* Debugging support */
6228 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6230 LLVMModuleRef module = lmodule->module;
6231 LLVMValueRef args [16], cu_args [16], cu, ver;
6233 char *build_info, *s, *dir;
6236 * This can only be enabled when LLVM code is emitted into a separate object
6237 * file, since the AOT compiler also emits dwarf info,
6238 * and the abbrev indexes will not be correct since llvm has added its own
6241 if (!lmodule->emit_dwarf)
6245 * Emit dwarf info in the form of LLVM metadata. There is some
6246 * out-of-date documentation at:
6247 * http://llvm.org/docs/SourceLevelDebugging.html
6248 * but most of this was gathered from the llvm and
6253 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6254 /* CU name/compilation dir */
6255 dir = g_path_get_dirname (filename);
6256 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6257 args [1] = LLVMMDString (dir, strlen (dir));
6258 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6261 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6263 build_info = mono_get_runtime_build_info ();
6264 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6265 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6266 g_free (build_info);
6268 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6270 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6271 /* Runtime version */
6272 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6274 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6275 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6277 if (lmodule->subprogram_mds) {
6281 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6282 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6283 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6284 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6286 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6289 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6290 /* Imported modules */
6291 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6293 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6294 /* DebugEmissionKind = FullDebug */
6295 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6296 cu = LLVMMDNode (cu_args, n_cuargs);
6297 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6299 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6300 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6301 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6302 ver = LLVMMDNode (args, 3);
6303 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6305 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6306 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6307 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6308 ver = LLVMMDNode (args, 3);
6309 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6313 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6315 MonoLLVMModule *module = ctx->lmodule;
6316 MonoDebugMethodInfo *minfo = ctx->minfo;
6317 char *source_file, *dir, *filename;
6318 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6319 MonoSymSeqPoint *sym_seq_points;
6325 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6327 source_file = g_strdup ("<unknown>");
6328 dir = g_path_get_dirname (source_file);
6329 filename = g_path_get_basename (source_file);
6331 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6332 args [0] = md_string (filename);
6333 args [1] = md_string (dir);
6334 ctx_args [1] = LLVMMDNode (args, 2);
6335 ctx_md = LLVMMDNode (ctx_args, 2);
6337 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6338 type_args [1] = NULL;
6339 type_args [2] = NULL;
6340 type_args [3] = LLVMMDString ("", 0);
6341 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6342 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6343 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6344 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6345 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6346 type_args [9] = NULL;
6347 type_args [10] = NULL;
6348 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6349 type_args [12] = NULL;
6350 type_args [13] = NULL;
6351 type_args [14] = NULL;
6352 type_md = LLVMMDNode (type_args, 14);
6354 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6355 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6356 /* Source directory + file pair */
6357 args [0] = md_string (filename);
6358 args [1] = md_string (dir);
6359 md_args [1] = LLVMMDNode (args ,2);
6360 md_args [2] = ctx_md;
6361 md_args [3] = md_string (cfg->method->name);
6362 md_args [4] = md_string (name);
6363 md_args [5] = md_string (name);
6366 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6368 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6370 md_args [7] = type_md;
6372 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6374 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6376 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6377 /* Index into a virtual function */
6378 md_args [11] = NULL;
6379 md_args [12] = NULL;
6381 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6383 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6384 /* Pointer to LLVM function */
6385 md_args [15] = method;
6386 /* Function template parameter */
6387 md_args [16] = NULL;
6388 /* Function declaration descriptor */
6389 md_args [17] = NULL;
6390 /* List of function variables */
6391 md_args [18] = LLVMMDNode (args, 0);
6393 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6394 md = LLVMMDNode (md_args, 20);
6396 if (!module->subprogram_mds)
6397 module->subprogram_mds = g_ptr_array_new ();
6398 g_ptr_array_add (module->subprogram_mds, md);
6402 g_free (source_file);
6403 g_free (sym_seq_points);
6409 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6411 MonoCompile *cfg = ctx->cfg;
6413 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6414 MonoDebugSourceLocation *loc;
6415 LLVMValueRef loc_md, md_args [16];
6418 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6422 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6423 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6424 md_args [nmd_args ++] = ctx->dbg_md;
6425 md_args [nmd_args ++] = NULL;
6426 loc_md = LLVMMDNode (md_args, nmd_args);
6427 LLVMSetCurrentDebugLocation (builder, loc_md);
6428 mono_debug_symfile_free_location (loc);
6435 - Emit LLVM IR from the mono IR using the LLVM C API.
6436 - The original arch specific code remains, so we can fall back to it if we run
6437 into something we can't handle.
6441 A partial list of issues:
6442 - Handling of opcodes which can throw exceptions.
6444 In the mono JIT, these are implemented using code like this:
6451 push throw_pos - method
6452 call <exception trampoline>
6454 The problematic part is push throw_pos - method, which cannot be represented
6455 in the LLVM IR, since it does not support label values.
6456 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6457 be implemented in JIT mode ?
6458 -> a possible but slower implementation would use the normal exception
6459 throwing code but it would need to control the placement of the throw code
6460 (it needs to be exactly after the compare+branch).
6461 -> perhaps add a PC offset intrinsics ?
6463 - efficient implementation of .ovf opcodes.
6465 These are currently implemented as:
6466 <ins which sets the condition codes>
6469 Some overflow opcodes are now supported by LLVM SVN.
6471 - exception handling, unwinding.
6472 - SSA is disabled for methods with exception handlers
6473 - How to obtain unwind info for LLVM compiled methods ?
6474 -> this is now solved by converting the unwind info generated by LLVM
6476 - LLVM uses the c++ exception handling framework, while we use our home grown
6477 code, and couldn't use the c++ one:
6478 - its not supported under VC++, other exotic platforms.
6479 - it might be impossible to support filter clauses with it.
6483 The trampolines need a predictable call sequence, since they need to disasm
6484 the calling code to obtain register numbers / offsets.
6486 LLVM currently generates this code in non-JIT mode:
6487 mov -0x98(%rax),%eax
6489 Here, the vtable pointer is lost.
6490 -> solution: use one vtable trampoline per class.
6492 - passing/receiving the IMT pointer/RGCTX.
6493 -> solution: pass them as normal arguments ?
6497 LLVM does not allow the specification of argument registers etc. This means
6498 that all calls are made according to the platform ABI.
6500 - passing/receiving vtypes.
6502 Vtypes passed/received in registers are handled by the front end by using
6503 a signature with scalar arguments, and loading the parts of the vtype into those
6506 Vtypes passed on the stack are handled using the 'byval' attribute.
6510 Supported though alloca, we need to emit the load/store code.
6514 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6515 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6516 This is made easier because the IR is already in SSA form.
6517 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6518 types are frequently used incorrectly.
6523 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6524 it with the file containing the methods emitted by the JIT and the AOT data
6528 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6529 * - each bblock should end with a branch
6530 * - setting the return value, making cfg->ret non-volatile
6531 * - avoid some transformations in the JIT which make it harder for us to generate
6533 * - use pointer types to help optimizations.