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) {
2699 //LLVM_FAILURE (ctx, "handler without invokes");
2702 emit_handler_start (ctx, bb, builder);
2703 CHECK_FAILURE (ctx);
2704 builder = ctx->builder;
2707 has_terminator = FALSE;
2708 starting_builder = builder;
2709 for (ins = bb->code; ins; ins = ins->next) {
2710 const char *spec = LLVM_INS_INFO (ins->opcode);
2712 char dname_buf [128];
2714 emit_dbg_loc (ctx, builder, ins->cil_code);
2717 if (nins > 3000 && builder == starting_builder) {
2718 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2719 LLVM_FAILURE (ctx, "basic block too long");
2723 /* There could be instructions after a terminator, skip them */
2726 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2727 sprintf (dname_buf, "t%d", ins->dreg);
2731 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2732 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2734 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2735 lhs = emit_volatile_load (ctx, ins->sreg1);
2737 /* It is ok for SETRET to have an uninitialized argument */
2738 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2739 LLVM_FAILURE (ctx, "sreg1");
2740 lhs = values [ins->sreg1];
2746 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2747 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2748 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2749 rhs = emit_volatile_load (ctx, ins->sreg2);
2751 if (!values [ins->sreg2])
2752 LLVM_FAILURE (ctx, "sreg2");
2753 rhs = values [ins->sreg2];
2759 //mono_print_ins (ins);
2760 switch (ins->opcode) {
2763 case OP_LIVERANGE_START:
2764 case OP_LIVERANGE_END:
2767 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2770 #if SIZEOF_VOID_P == 4
2771 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2773 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2777 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2781 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2783 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2785 case OP_DUMMY_ICONST:
2786 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2788 case OP_DUMMY_I8CONST:
2789 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2791 case OP_DUMMY_R8CONST:
2792 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2795 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2796 has_terminator = TRUE;
2802 LLVMBasicBlockRef new_bb;
2803 LLVMBuilderRef new_builder;
2805 // The default branch is already handled
2806 // FIXME: Handle it here
2808 /* Start new bblock */
2809 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2810 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2812 lhs = convert (ctx, lhs, LLVMInt32Type ());
2813 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2814 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2815 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2817 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2820 new_builder = create_builder (ctx);
2821 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2822 LLVMBuildUnreachable (new_builder);
2824 has_terminator = TRUE;
2825 g_assert (!ins->next);
2831 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2832 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2833 LLVMValueRef part1, retval;
2836 size = get_vtype_size (sig->ret);
2838 g_assert (addresses [ins->sreg1]);
2840 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2841 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2843 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2845 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2847 LLVMBuildRet (builder, retval);
2851 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2852 LLVMValueRef retval;
2854 g_assert (addresses [ins->sreg1]);
2855 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2856 LLVMBuildRet (builder, retval);
2860 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2861 LLVMBuildRetVoid (builder);
2865 if (linfo->ret.storage == LLVMArgFpStruct) {
2866 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2867 LLVMValueRef retval;
2869 g_assert (addresses [ins->sreg1]);
2870 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2871 LLVMBuildRet (builder, retval);
2875 if (!lhs || ctx->is_dead [ins->sreg1]) {
2877 * The method did not set its return value, probably because it
2878 * ends with a throw.
2881 LLVMBuildRetVoid (builder);
2883 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2885 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2887 has_terminator = TRUE;
2894 case OP_ICOMPARE_IMM:
2895 case OP_LCOMPARE_IMM:
2896 case OP_COMPARE_IMM: {
2900 if (ins->next->opcode == OP_NOP)
2903 if (ins->next->opcode == OP_BR)
2904 /* The comparison result is not needed */
2907 rel = mono_opcode_to_cond (ins->next->opcode);
2909 if (ins->opcode == OP_ICOMPARE_IMM) {
2910 lhs = convert (ctx, lhs, LLVMInt32Type ());
2911 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2913 if (ins->opcode == OP_LCOMPARE_IMM) {
2914 lhs = convert (ctx, lhs, LLVMInt64Type ());
2915 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2917 if (ins->opcode == OP_LCOMPARE) {
2918 lhs = convert (ctx, lhs, LLVMInt64Type ());
2919 rhs = convert (ctx, rhs, LLVMInt64Type ());
2921 if (ins->opcode == OP_ICOMPARE) {
2922 lhs = convert (ctx, lhs, LLVMInt32Type ());
2923 rhs = convert (ctx, rhs, LLVMInt32Type ());
2927 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2928 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2929 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2930 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2933 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2934 if (ins->opcode == OP_FCOMPARE) {
2935 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2936 } else if (ins->opcode == OP_RCOMPARE) {
2937 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2938 } else if (ins->opcode == OP_COMPARE_IMM) {
2939 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2940 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2942 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2943 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2944 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2945 /* The immediate is encoded in two fields */
2946 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2947 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2949 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2952 else if (ins->opcode == OP_COMPARE) {
2953 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2954 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2956 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2958 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2960 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2961 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2963 * If the target bb contains PHI instructions, LLVM requires
2964 * two PHI entries for this bblock, while we only generate one.
2965 * So convert this to an unconditional bblock. (bxc #171).
2967 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2969 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2971 has_terminator = TRUE;
2972 } else if (MONO_IS_SETCC (ins->next)) {
2973 sprintf (dname_buf, "t%d", ins->next->dreg);
2975 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2977 /* Add stores for volatile variables */
2978 emit_volatile_store (ctx, ins->next->dreg);
2979 } else if (MONO_IS_COND_EXC (ins->next)) {
2980 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2981 CHECK_FAILURE (ctx);
2982 builder = ctx->builder;
2984 LLVM_FAILURE (ctx, "next");
2998 rel = mono_opcode_to_cond (ins->opcode);
3000 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3001 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3012 rel = mono_opcode_to_cond (ins->opcode);
3014 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3015 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3023 gboolean empty = TRUE;
3025 /* Check that all input bblocks really branch to us */
3026 for (i = 0; i < bb->in_count; ++i) {
3027 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3028 ins->inst_phi_args [i + 1] = -1;
3034 /* LLVM doesn't like phi instructions with zero operands */
3035 ctx->is_dead [ins->dreg] = TRUE;
3039 /* Created earlier, insert it now */
3040 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3042 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3043 int sreg1 = ins->inst_phi_args [i + 1];
3047 * Count the number of times the incoming bblock branches to us,
3048 * since llvm requires a separate entry for each.
3050 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3051 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3054 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3055 if (switch_ins->inst_many_bb [j] == bb)
3062 /* Remember for later */
3063 for (j = 0; j < count; ++j) {
3064 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3067 node->in_bb = bb->in_bb [i];
3069 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);
3079 values [ins->dreg] = lhs;
3083 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3086 values [ins->dreg] = lhs;
3088 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3090 * This is added by the spilling pass in case of the JIT,
3091 * but we have to do it ourselves.
3093 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3097 case OP_MOVE_F_TO_I4: {
3098 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3101 case OP_MOVE_I4_TO_F: {
3102 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3105 case OP_MOVE_F_TO_I8: {
3106 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3109 case OP_MOVE_I8_TO_F: {
3110 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3143 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3144 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3146 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3147 CHECK_FAILURE (ctx);
3148 builder = ctx->builder;
3150 switch (ins->opcode) {
3153 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3157 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3161 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3165 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3169 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3173 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3177 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3181 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3185 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3189 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3193 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3197 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3201 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3205 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3209 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3212 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3215 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3219 g_assert_not_reached ();
3226 lhs = convert (ctx, lhs, LLVMFloatType ());
3227 rhs = convert (ctx, rhs, LLVMFloatType ());
3228 switch (ins->opcode) {
3230 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3233 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3236 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3239 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3242 g_assert_not_reached ();
3251 case OP_IREM_UN_IMM:
3253 case OP_IDIV_UN_IMM:
3259 case OP_ISHR_UN_IMM:
3268 case OP_LSHR_UN_IMM:
3274 case OP_SHR_UN_IMM: {
3277 if (spec [MONO_INST_SRC1] == 'l') {
3278 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3280 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3283 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3284 CHECK_FAILURE (ctx);
3285 builder = ctx->builder;
3287 #if SIZEOF_VOID_P == 4
3288 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3289 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3292 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3293 lhs = convert (ctx, lhs, IntPtrType ());
3294 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3295 switch (ins->opcode) {
3299 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3303 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3307 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3311 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3313 case OP_IDIV_UN_IMM:
3314 case OP_LDIV_UN_IMM:
3315 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3319 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3321 case OP_IREM_UN_IMM:
3322 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3327 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3331 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3335 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3340 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3345 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3347 case OP_ISHR_UN_IMM:
3348 /* This is used to implement conv.u4, so the lhs could be an i8 */
3349 lhs = convert (ctx, lhs, LLVMInt32Type ());
3350 imm = convert (ctx, imm, LLVMInt32Type ());
3351 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3353 case OP_LSHR_UN_IMM:
3355 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3358 g_assert_not_reached ();
3363 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3366 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3369 lhs = convert (ctx, lhs, LLVMDoubleType ());
3370 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3373 lhs = convert (ctx, lhs, LLVMFloatType ());
3374 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3377 guint32 v = 0xffffffff;
3378 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3382 guint64 v = 0xffffffffffffffffLL;
3383 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3386 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3388 LLVMValueRef v1, v2;
3390 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3391 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3392 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3397 case OP_ICONV_TO_I1:
3398 case OP_ICONV_TO_I2:
3399 case OP_ICONV_TO_I4:
3400 case OP_ICONV_TO_U1:
3401 case OP_ICONV_TO_U2:
3402 case OP_ICONV_TO_U4:
3403 case OP_LCONV_TO_I1:
3404 case OP_LCONV_TO_I2:
3405 case OP_LCONV_TO_U1:
3406 case OP_LCONV_TO_U2:
3407 case OP_LCONV_TO_U4: {
3410 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);
3412 /* Have to do two casts since our vregs have type int */
3413 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3415 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3417 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3420 case OP_ICONV_TO_I8:
3421 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3423 case OP_ICONV_TO_U8:
3424 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3426 case OP_FCONV_TO_I4:
3427 case OP_RCONV_TO_I4:
3428 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3430 case OP_FCONV_TO_I1:
3431 case OP_RCONV_TO_I1:
3432 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3434 case OP_FCONV_TO_U1:
3435 case OP_RCONV_TO_U1:
3436 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3438 case OP_FCONV_TO_I2:
3439 case OP_RCONV_TO_I2:
3440 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3442 case OP_FCONV_TO_U2:
3443 case OP_RCONV_TO_U2:
3444 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3446 case OP_FCONV_TO_I8:
3447 case OP_RCONV_TO_I8:
3448 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3451 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3453 case OP_ICONV_TO_R8:
3454 case OP_LCONV_TO_R8:
3455 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3457 case OP_LCONV_TO_R_UN:
3458 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3460 #if SIZEOF_VOID_P == 4
3463 case OP_LCONV_TO_I4:
3464 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3466 case OP_ICONV_TO_R4:
3467 case OP_LCONV_TO_R4:
3468 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3470 values [ins->dreg] = v;
3472 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3474 case OP_FCONV_TO_R4:
3475 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3477 values [ins->dreg] = v;
3479 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3481 case OP_RCONV_TO_R8:
3482 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3484 case OP_RCONV_TO_R4:
3485 values [ins->dreg] = lhs;
3488 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3491 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3494 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3496 case OP_LOCALLOC_IMM: {
3499 guint32 size = ins->inst_imm;
3500 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3502 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3504 if (ins->flags & MONO_INST_INIT) {
3505 LLVMValueRef args [5];
3508 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3509 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3510 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3511 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3512 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3515 values [ins->dreg] = v;
3519 LLVMValueRef v, size;
3521 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), "");
3523 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3525 if (ins->flags & MONO_INST_INIT) {
3526 LLVMValueRef args [5];
3529 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3531 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3532 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3533 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3535 values [ins->dreg] = v;
3539 case OP_LOADI1_MEMBASE:
3540 case OP_LOADU1_MEMBASE:
3541 case OP_LOADI2_MEMBASE:
3542 case OP_LOADU2_MEMBASE:
3543 case OP_LOADI4_MEMBASE:
3544 case OP_LOADU4_MEMBASE:
3545 case OP_LOADI8_MEMBASE:
3546 case OP_LOADR4_MEMBASE:
3547 case OP_LOADR8_MEMBASE:
3548 case OP_LOAD_MEMBASE:
3556 LLVMValueRef base, index, addr;
3558 gboolean sext = FALSE, zext = FALSE;
3559 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3561 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3566 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)) {
3567 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3572 if (ins->inst_offset == 0) {
3574 } else if (ins->inst_offset % size != 0) {
3575 /* Unaligned load */
3576 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3577 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3579 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3580 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3584 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3586 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3588 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3590 * These will signal LLVM that these loads do not alias any stores, and
3591 * they can't fail, allowing them to be hoisted out of loops.
3593 set_invariant_load_flag (values [ins->dreg]);
3594 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3598 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3600 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3601 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3602 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3606 case OP_STOREI1_MEMBASE_REG:
3607 case OP_STOREI2_MEMBASE_REG:
3608 case OP_STOREI4_MEMBASE_REG:
3609 case OP_STOREI8_MEMBASE_REG:
3610 case OP_STORER4_MEMBASE_REG:
3611 case OP_STORER8_MEMBASE_REG:
3612 case OP_STORE_MEMBASE_REG: {
3614 LLVMValueRef index, addr;
3616 gboolean sext = FALSE, zext = FALSE;
3617 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3619 if (!values [ins->inst_destbasereg])
3620 LLVM_FAILURE (ctx, "inst_destbasereg");
3622 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3624 if (ins->inst_offset % size != 0) {
3625 /* Unaligned store */
3626 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3627 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3629 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3630 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3632 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3636 case OP_STOREI1_MEMBASE_IMM:
3637 case OP_STOREI2_MEMBASE_IMM:
3638 case OP_STOREI4_MEMBASE_IMM:
3639 case OP_STOREI8_MEMBASE_IMM:
3640 case OP_STORE_MEMBASE_IMM: {
3642 LLVMValueRef index, addr;
3644 gboolean sext = FALSE, zext = FALSE;
3645 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3647 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3649 if (ins->inst_offset % size != 0) {
3650 /* Unaligned store */
3651 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3652 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3654 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3655 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3657 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3662 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3664 case OP_OUTARG_VTRETADDR:
3672 case OP_VOIDCALL_MEMBASE:
3673 case OP_CALL_MEMBASE:
3674 case OP_LCALL_MEMBASE:
3675 case OP_FCALL_MEMBASE:
3676 case OP_RCALL_MEMBASE:
3677 case OP_VCALL_MEMBASE:
3678 case OP_VOIDCALL_REG:
3683 case OP_VCALL_REG: {
3684 process_call (ctx, bb, &builder, ins);
3685 CHECK_FAILURE (ctx);
3690 LLVMValueRef indexes [2];
3692 LLVMValueRef got_entry_addr;
3695 * FIXME: Can't allocate from the cfg mempool since that is freed if
3696 * the LLVM compile fails.
3698 ji = g_new0 (MonoJumpInfo, 1);
3699 ji->type = (MonoJumpInfoType)ins->inst_i1;
3700 ji->data.target = ins->inst_p0;
3702 ji = mono_aot_patch_info_dup (ji);
3704 ji->next = cfg->patch_info;
3705 cfg->patch_info = ji;
3707 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3708 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3709 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3711 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3712 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3713 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3715 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3716 set_invariant_load_flag (values [ins->dreg]);
3719 case OP_NOT_REACHED:
3720 LLVMBuildUnreachable (builder);
3721 has_terminator = TRUE;
3722 g_assert (bb->block_num < cfg->max_block_num);
3723 ctx->unreachable [bb->block_num] = TRUE;
3724 /* Might have instructions after this */
3726 MonoInst *next = ins->next;
3728 * FIXME: If later code uses the regs defined by these instructions,
3729 * compilation will fail.
3731 MONO_DELETE_INS (bb, next);
3735 MonoInst *var = ins->inst_p0;
3737 values [ins->dreg] = addresses [var->dreg];
3741 LLVMValueRef args [1];
3743 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3744 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3748 LLVMValueRef args [1];
3750 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3751 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3755 LLVMValueRef args [1];
3758 /* This no longer seems to happen */
3760 * LLVM optimizes sqrt(nan) into undefined in
3761 * lib/Analysis/ConstantFolding.cpp
3762 * Also, sqrt(NegativeInfinity) is optimized into 0.
3764 LLVM_FAILURE (ctx, "sqrt");
3766 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3767 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3771 LLVMValueRef args [1];
3773 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3774 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3788 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3789 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3791 switch (ins->opcode) {
3794 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3798 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3802 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3806 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3809 g_assert_not_reached ();
3812 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3815 case OP_ATOMIC_EXCHANGE_I4:
3816 case OP_ATOMIC_EXCHANGE_I8: {
3817 LLVMValueRef args [2];
3820 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3821 t = LLVMInt32Type ();
3823 t = LLVMInt64Type ();
3825 g_assert (ins->inst_offset == 0);
3827 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3828 args [1] = convert (ctx, rhs, t);
3830 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3833 case OP_ATOMIC_ADD_I4:
3834 case OP_ATOMIC_ADD_I8: {
3835 LLVMValueRef args [2];
3838 if (ins->opcode == OP_ATOMIC_ADD_I4)
3839 t = LLVMInt32Type ();
3841 t = LLVMInt64Type ();
3843 g_assert (ins->inst_offset == 0);
3845 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3846 args [1] = convert (ctx, rhs, t);
3847 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3850 case OP_ATOMIC_CAS_I4:
3851 case OP_ATOMIC_CAS_I8: {
3852 LLVMValueRef args [3], val;
3855 if (ins->opcode == OP_ATOMIC_CAS_I4)
3856 t = LLVMInt32Type ();
3858 t = LLVMInt64Type ();
3860 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3862 args [1] = convert (ctx, values [ins->sreg3], t);
3864 args [2] = convert (ctx, values [ins->sreg2], t);
3865 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3866 /* cmpxchg returns a pair */
3867 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3870 case OP_MEMORY_BARRIER: {
3871 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3874 case OP_ATOMIC_LOAD_I1:
3875 case OP_ATOMIC_LOAD_I2:
3876 case OP_ATOMIC_LOAD_I4:
3877 case OP_ATOMIC_LOAD_I8:
3878 case OP_ATOMIC_LOAD_U1:
3879 case OP_ATOMIC_LOAD_U2:
3880 case OP_ATOMIC_LOAD_U4:
3881 case OP_ATOMIC_LOAD_U8:
3882 case OP_ATOMIC_LOAD_R4:
3883 case OP_ATOMIC_LOAD_R8: {
3884 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3887 gboolean sext, zext;
3889 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3890 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3891 LLVMValueRef index, addr;
3893 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3898 if (ins->inst_offset != 0) {
3899 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3900 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3905 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3907 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3910 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3912 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3915 case OP_ATOMIC_STORE_I1:
3916 case OP_ATOMIC_STORE_I2:
3917 case OP_ATOMIC_STORE_I4:
3918 case OP_ATOMIC_STORE_I8:
3919 case OP_ATOMIC_STORE_U1:
3920 case OP_ATOMIC_STORE_U2:
3921 case OP_ATOMIC_STORE_U4:
3922 case OP_ATOMIC_STORE_U8:
3923 case OP_ATOMIC_STORE_R4:
3924 case OP_ATOMIC_STORE_R8: {
3925 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3928 gboolean sext, zext;
3930 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3931 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3932 LLVMValueRef index, addr, value;
3934 if (!values [ins->inst_destbasereg])
3935 LLVM_FAILURE (ctx, "inst_destbasereg");
3937 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3939 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3940 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3941 value = convert (ctx, values [ins->sreg1], t);
3943 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3946 case OP_RELAXED_NOP: {
3947 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3948 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3955 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3957 // 257 == FS segment register
3958 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3960 // 256 == GS segment register
3961 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3964 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3965 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3966 /* See mono_amd64_emit_tls_get () */
3967 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3969 // 256 == GS segment register
3970 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3971 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3973 LLVM_FAILURE (ctx, "opcode tls-get");
3978 case OP_TLS_GET_REG: {
3979 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3980 /* See emit_tls_get_reg () */
3981 // 256 == GS segment register
3982 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3983 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3985 LLVM_FAILURE (ctx, "opcode tls-get");
3994 case OP_IADD_OVF_UN:
3996 case OP_ISUB_OVF_UN:
3998 case OP_IMUL_OVF_UN:
3999 #if SIZEOF_VOID_P == 8
4001 case OP_LADD_OVF_UN:
4003 case OP_LSUB_OVF_UN:
4005 case OP_LMUL_OVF_UN:
4008 LLVMValueRef args [2], val, ovf, func;
4010 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4011 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4012 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4014 val = LLVMBuildCall (builder, func, args, 2, "");
4015 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4016 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4017 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4018 CHECK_FAILURE (ctx);
4019 builder = ctx->builder;
4025 * We currently model them using arrays. Promotion to local vregs is
4026 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4027 * so we always have an entry in cfg->varinfo for them.
4028 * FIXME: Is this needed ?
4031 MonoClass *klass = ins->klass;
4032 LLVMValueRef args [5];
4036 LLVM_FAILURE (ctx, "!klass");
4040 if (!addresses [ins->dreg])
4041 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4042 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4043 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4044 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4046 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4047 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4048 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4051 case OP_DUMMY_VZERO:
4054 case OP_STOREV_MEMBASE:
4055 case OP_LOADV_MEMBASE:
4057 MonoClass *klass = ins->klass;
4058 LLVMValueRef src = NULL, dst, args [5];
4059 gboolean done = FALSE;
4063 LLVM_FAILURE (ctx, "!klass");
4067 if (mini_is_gsharedvt_klass (cfg, klass)) {
4069 LLVM_FAILURE (ctx, "gsharedvt");
4073 switch (ins->opcode) {
4074 case OP_STOREV_MEMBASE:
4075 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4076 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4077 /* Decomposed earlier */
4078 g_assert_not_reached ();
4081 if (!addresses [ins->sreg1]) {
4083 g_assert (values [ins->sreg1]);
4084 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));
4085 LLVMBuildStore (builder, values [ins->sreg1], dst);
4088 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4089 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4092 case OP_LOADV_MEMBASE:
4093 if (!addresses [ins->dreg])
4094 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4095 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4096 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4099 if (!addresses [ins->sreg1])
4100 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4101 if (!addresses [ins->dreg])
4102 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4103 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4104 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4107 g_assert_not_reached ();
4109 CHECK_FAILURE (ctx);
4116 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4117 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4119 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4120 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4121 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4124 case OP_LLVM_OUTARG_VT:
4125 if (!addresses [ins->sreg1]) {
4126 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4127 g_assert (values [ins->sreg1]);
4128 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4130 addresses [ins->dreg] = addresses [ins->sreg1];
4136 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4138 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4141 case OP_LOADX_MEMBASE: {
4142 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4145 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4146 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4149 case OP_STOREX_MEMBASE: {
4150 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4153 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4154 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4161 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4165 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4171 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4175 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4179 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4183 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4186 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4189 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4192 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4196 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4207 LLVMValueRef v = NULL;
4209 switch (ins->opcode) {
4214 t = LLVMVectorType (LLVMInt32Type (), 4);
4215 rt = LLVMVectorType (LLVMFloatType (), 4);
4221 t = LLVMVectorType (LLVMInt64Type (), 2);
4222 rt = LLVMVectorType (LLVMDoubleType (), 2);
4225 t = LLVMInt32Type ();
4226 rt = LLVMInt32Type ();
4227 g_assert_not_reached ();
4230 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4231 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4232 switch (ins->opcode) {
4235 v = LLVMBuildAnd (builder, lhs, rhs, "");
4239 v = LLVMBuildOr (builder, lhs, rhs, "");
4243 v = LLVMBuildXor (builder, lhs, rhs, "");
4247 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4250 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4274 case OP_PADDB_SAT_UN:
4275 case OP_PADDW_SAT_UN:
4276 case OP_PSUBB_SAT_UN:
4277 case OP_PSUBW_SAT_UN:
4285 case OP_PMULW_HIGH_UN: {
4286 LLVMValueRef args [2];
4291 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4298 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4302 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4310 case OP_EXTRACTX_U2:
4312 case OP_EXTRACT_U1: {
4314 gboolean zext = FALSE;
4316 t = simd_op_to_llvm_type (ins->opcode);
4318 switch (ins->opcode) {
4326 case OP_EXTRACTX_U2:
4331 t = LLVMInt32Type ();
4332 g_assert_not_reached ();
4335 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4336 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4338 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4347 case OP_EXPAND_R8: {
4348 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4349 LLVMValueRef mask [16], v;
4352 for (i = 0; i < 16; ++i)
4353 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4355 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4357 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4358 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4363 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4366 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4369 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4372 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4375 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4378 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4389 case OP_EXTRACT_MASK:
4396 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4398 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4404 LLVMValueRef args [3];
4408 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4410 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4415 /* This is only used for implementing shifts by non-immediate */
4416 values [ins->dreg] = lhs;
4427 LLVMValueRef args [3];
4430 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4432 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4443 case OP_PSHLQ_REG: {
4444 LLVMValueRef args [3];
4447 args [1] = values [ins->sreg2];
4449 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4456 case OP_PSHUFLEW_LOW:
4457 case OP_PSHUFLEW_HIGH: {
4459 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4460 int i, mask_size = 0;
4461 int imask = ins->inst_c0;
4463 /* Convert the x86 shuffle mask to LLVM's */
4464 switch (ins->opcode) {
4467 mask [0] = ((imask >> 0) & 3);
4468 mask [1] = ((imask >> 2) & 3);
4469 mask [2] = ((imask >> 4) & 3) + 4;
4470 mask [3] = ((imask >> 6) & 3) + 4;
4471 v1 = values [ins->sreg1];
4472 v2 = values [ins->sreg2];
4476 mask [0] = ((imask >> 0) & 1);
4477 mask [1] = ((imask >> 1) & 1) + 2;
4478 v1 = values [ins->sreg1];
4479 v2 = values [ins->sreg2];
4481 case OP_PSHUFLEW_LOW:
4483 mask [0] = ((imask >> 0) & 3);
4484 mask [1] = ((imask >> 2) & 3);
4485 mask [2] = ((imask >> 4) & 3);
4486 mask [3] = ((imask >> 6) & 3);
4491 v1 = values [ins->sreg1];
4492 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4494 case OP_PSHUFLEW_HIGH:
4500 mask [4] = 4 + ((imask >> 0) & 3);
4501 mask [5] = 4 + ((imask >> 2) & 3);
4502 mask [6] = 4 + ((imask >> 4) & 3);
4503 mask [7] = 4 + ((imask >> 6) & 3);
4504 v1 = values [ins->sreg1];
4505 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4509 mask [0] = ((imask >> 0) & 3);
4510 mask [1] = ((imask >> 2) & 3);
4511 mask [2] = ((imask >> 4) & 3);
4512 mask [3] = ((imask >> 6) & 3);
4513 v1 = values [ins->sreg1];
4514 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4517 g_assert_not_reached ();
4519 for (i = 0; i < mask_size; ++i)
4520 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4522 values [ins->dreg] =
4523 LLVMBuildShuffleVector (builder, v1, v2,
4524 LLVMConstVector (mask_values, mask_size), dname);
4528 case OP_UNPACK_LOWB:
4529 case OP_UNPACK_LOWW:
4530 case OP_UNPACK_LOWD:
4531 case OP_UNPACK_LOWQ:
4532 case OP_UNPACK_LOWPS:
4533 case OP_UNPACK_LOWPD:
4534 case OP_UNPACK_HIGHB:
4535 case OP_UNPACK_HIGHW:
4536 case OP_UNPACK_HIGHD:
4537 case OP_UNPACK_HIGHQ:
4538 case OP_UNPACK_HIGHPS:
4539 case OP_UNPACK_HIGHPD: {
4541 LLVMValueRef mask_values [16];
4542 int i, mask_size = 0;
4543 gboolean low = FALSE;
4545 switch (ins->opcode) {
4546 case OP_UNPACK_LOWB:
4550 case OP_UNPACK_LOWW:
4554 case OP_UNPACK_LOWD:
4555 case OP_UNPACK_LOWPS:
4559 case OP_UNPACK_LOWQ:
4560 case OP_UNPACK_LOWPD:
4564 case OP_UNPACK_HIGHB:
4567 case OP_UNPACK_HIGHW:
4570 case OP_UNPACK_HIGHD:
4571 case OP_UNPACK_HIGHPS:
4574 case OP_UNPACK_HIGHQ:
4575 case OP_UNPACK_HIGHPD:
4579 g_assert_not_reached ();
4583 for (i = 0; i < (mask_size / 2); ++i) {
4585 mask [(i * 2) + 1] = mask_size + i;
4588 for (i = 0; i < (mask_size / 2); ++i) {
4589 mask [(i * 2)] = (mask_size / 2) + i;
4590 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4594 for (i = 0; i < mask_size; ++i)
4595 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4597 values [ins->dreg] =
4598 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4599 LLVMConstVector (mask_values, mask_size), dname);
4604 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4605 LLVMValueRef v, val;
4607 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4608 val = LLVMConstNull (t);
4609 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4610 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4612 values [ins->dreg] = val;
4616 case OP_DUPPS_HIGH: {
4617 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4618 LLVMValueRef v1, v2, val;
4621 if (ins->opcode == OP_DUPPS_LOW) {
4622 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4623 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4625 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4626 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4628 val = LLVMConstNull (t);
4629 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4630 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4631 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4632 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4634 values [ins->dreg] = val;
4644 * EXCEPTION HANDLING
4646 case OP_IMPLICIT_EXCEPTION:
4647 /* This marks a place where an implicit exception can happen */
4648 if (bb->region != -1)
4649 LLVM_FAILURE (ctx, "implicit-exception");
4653 MonoMethodSignature *throw_sig;
4654 LLVMValueRef callee, arg;
4655 gboolean rethrow = (ins->opcode == OP_RETHROW);
4656 const char *icall_name;
4658 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4659 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4662 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4663 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4664 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4665 if (cfg->compile_aot) {
4666 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4668 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4672 * LLVM doesn't push the exception argument, so we need a different
4675 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4677 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4681 mono_memory_barrier ();
4683 ctx->lmodule->rethrow = callee;
4685 ctx->lmodule->throw = callee;
4687 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4688 emit_call (ctx, bb, &builder, callee, &arg, 1);
4691 case OP_CALL_HANDLER: {
4693 * We don't 'call' handlers, but instead simply branch to them.
4694 * The code generated by ENDFINALLY will branch back to us.
4696 LLVMBasicBlockRef noex_bb;
4698 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4700 bb_list = info->call_handler_return_bbs;
4703 * Set the indicator variable for the finally clause.
4705 lhs = info->finally_ind;
4707 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4709 /* Branch to the finally clause */
4710 LLVMBuildBr (builder, info->call_handler_target_bb);
4712 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4713 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4715 builder = ctx->builder = create_builder (ctx);
4716 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4718 bblocks [bb->block_num].end_bblock = noex_bb;
4721 case OP_START_HANDLER: {
4724 case OP_ENDFINALLY: {
4725 LLVMBasicBlockRef resume_bb;
4726 MonoBasicBlock *handler_bb;
4727 LLVMValueRef val, switch_ins, callee;
4731 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4732 g_assert (handler_bb);
4733 info = &bblocks [handler_bb->block_num];
4734 lhs = info->finally_ind;
4737 bb_list = info->call_handler_return_bbs;
4739 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4741 /* Load the finally variable */
4742 val = LLVMBuildLoad (builder, lhs, "");
4744 /* Reset the variable */
4745 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4747 /* Branch to either resume_bb, or to the bblocks in bb_list */
4748 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4750 * The other targets are added at the end to handle OP_CALL_HANDLER
4751 * opcodes processed later.
4753 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4755 builder = ctx->builder = create_builder (ctx);
4756 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4758 if (ctx->cfg->compile_aot) {
4759 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4761 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4763 LLVMBuildCall (builder, callee, NULL, 0, "");
4765 LLVMBuildUnreachable (builder);
4766 has_terminator = TRUE;
4772 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4773 LLVM_FAILURE (ctx, reason);
4778 /* Convert the value to the type required by phi nodes */
4779 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4780 if (!values [ins->dreg])
4782 values [ins->dreg] = addresses [ins->dreg];
4784 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4787 /* Add stores for volatile variables */
4788 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4789 emit_volatile_store (ctx, ins->dreg);
4792 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4793 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4795 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4796 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4797 LLVMBuildRetVoid (builder);
4800 if (bb == cfg->bb_entry)
4801 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4810 * mono_llvm_check_method_supported:
4812 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4813 * compiling a method twice.
4816 mono_llvm_check_method_supported (MonoCompile *cfg)
4820 if (cfg->method->save_lmf) {
4821 cfg->exception_message = g_strdup ("lmf");
4822 cfg->disable_llvm = TRUE;
4824 if (cfg->disable_llvm)
4828 * Nested clauses where one of the clauses is a finally clause is
4829 * not supported, because LLVM can't figure out the control flow,
4830 * probably because we resume exception handling by calling our
4831 * own function instead of using the 'resume' llvm instruction.
4833 for (i = 0; i < cfg->header->num_clauses; ++i) {
4834 for (j = 0; j < cfg->header->num_clauses; ++j) {
4835 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4836 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4838 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4839 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4840 cfg->exception_message = g_strdup ("nested clauses");
4841 cfg->disable_llvm = TRUE;
4846 if (cfg->disable_llvm)
4850 if (cfg->method->dynamic) {
4851 cfg->exception_message = g_strdup ("dynamic.");
4852 cfg->disable_llvm = TRUE;
4854 if (cfg->disable_llvm)
4859 * mono_llvm_emit_method:
4861 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4864 mono_llvm_emit_method (MonoCompile *cfg)
4867 MonoMethodSignature *sig;
4869 LLVMTypeRef method_type;
4870 LLVMValueRef method = NULL;
4872 LLVMValueRef *values;
4873 int i, max_block_num, bb_index;
4874 gboolean last = FALSE;
4875 GPtrArray *phi_values;
4876 LLVMCallInfo *linfo;
4878 LLVMModuleRef module;
4880 GPtrArray *bblock_list;
4881 MonoMethodHeader *header;
4882 MonoExceptionClause *clause;
4886 /* The code below might acquire the loader lock, so use it for global locking */
4887 mono_loader_lock ();
4889 /* Used to communicate with the callbacks */
4890 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4892 ctx = g_new0 (EmitContext, 1);
4894 ctx->mempool = cfg->mempool;
4897 * This maps vregs to the LLVM instruction defining them
4899 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4901 * This maps vregs for volatile variables to the LLVM instruction defining their
4904 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4905 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4906 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4907 phi_values = g_ptr_array_sized_new (256);
4909 * This signals whenever the vreg was defined by a phi node with no input vars
4910 * (i.e. all its input bblocks end with NOT_REACHABLE).
4912 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4913 /* Whenever the bblock is unreachable */
4914 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4916 bblock_list = g_ptr_array_sized_new (256);
4918 ctx->values = values;
4919 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4920 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4922 if (cfg->compile_aot) {
4923 ctx->lmodule = &aot_module;
4924 method_name = mono_aot_get_method_name (cfg);
4925 cfg->llvm_method_name = g_strdup (method_name);
4927 init_jit_module (cfg->domain);
4928 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4929 method_name = mono_method_full_name (cfg->method, TRUE);
4932 module = ctx->module = ctx->lmodule->module;
4935 LLVM_FAILURE (ctx, "gsharedvt");
4939 static int count = 0;
4942 if (g_getenv ("LLVM_COUNT")) {
4943 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4944 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4948 if (count > atoi (g_getenv ("LLVM_COUNT")))
4949 LLVM_FAILURE (ctx, "");
4954 sig = mono_method_signature (cfg->method);
4957 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4959 CHECK_FAILURE (ctx);
4962 linfo->rgctx_arg = TRUE;
4963 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4964 CHECK_FAILURE (ctx);
4967 * This maps parameter indexes in the original signature to the indexes in
4968 * the LLVM signature.
4970 ctx->pindexes = sinfo.pindexes;
4972 method = LLVMAddFunction (module, method_name, method_type);
4973 ctx->lmethod = method;
4975 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4976 LLVMSetLinkage (method, LLVMPrivateLinkage);
4978 LLVMAddFunctionAttr (method, LLVMUWTable);
4980 if (cfg->compile_aot) {
4981 LLVMSetLinkage (method, LLVMInternalLinkage);
4982 if (ctx->lmodule->external_symbols) {
4983 LLVMSetLinkage (method, LLVMExternalLinkage);
4984 LLVMSetVisibility (method, LLVMHiddenVisibility);
4987 LLVMSetLinkage (method, LLVMPrivateLinkage);
4990 if (cfg->method->save_lmf)
4991 LLVM_FAILURE (ctx, "lmf");
4993 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4994 LLVM_FAILURE (ctx, "pinvoke signature");
4996 header = cfg->header;
4997 for (i = 0; i < header->num_clauses; ++i) {
4998 clause = &header->clauses [i];
4999 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5000 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5002 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5003 /* We can't handle inlined methods with clauses */
5004 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5006 if (linfo->rgctx_arg) {
5007 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5009 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5010 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5011 * CC_X86_64_Mono in X86CallingConv.td.
5013 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5014 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5016 if (cfg->vret_addr) {
5017 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5018 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5021 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5022 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5025 names = g_new (char *, sig->param_count);
5026 mono_method_get_param_names (cfg->method, (const char **) names);
5028 for (i = 0; i < sig->param_count; ++i) {
5031 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5032 if (names [i] && names [i][0] != '\0')
5033 name = g_strdup_printf ("arg_%s", names [i]);
5035 name = g_strdup_printf ("arg_%d", i);
5036 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5038 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5039 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5043 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5044 ctx->minfo = mono_debug_lookup_method (cfg->method);
5045 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5049 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5050 max_block_num = MAX (max_block_num, bb->block_num);
5051 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5053 /* Add branches between non-consecutive bblocks */
5054 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5055 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5056 bb->next_bb != bb->last_ins->inst_false_bb) {
5058 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5059 inst->opcode = OP_BR;
5060 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5061 mono_bblock_add_inst (bb, inst);
5066 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5067 * was later optimized away, so clear these flags, and add them back for the still
5068 * present OP_LDADDR instructions.
5070 for (i = 0; i < cfg->next_vreg; ++i) {
5073 ins = get_vreg_to_inst (cfg, i);
5074 if (ins && ins != cfg->rgctx_var)
5075 ins->flags &= ~MONO_INST_INDIRECT;
5079 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5081 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5083 LLVMBuilderRef builder;
5085 char dname_buf[128];
5087 builder = create_builder (ctx);
5089 for (ins = bb->code; ins; ins = ins->next) {
5090 switch (ins->opcode) {
5095 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5097 CHECK_FAILURE (ctx);
5099 if (ins->opcode == OP_VPHI) {
5100 /* Treat valuetype PHI nodes as operating on the address itself */
5101 g_assert (ins->klass);
5102 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5106 * Have to precreate these, as they can be referenced by
5107 * earlier instructions.
5109 sprintf (dname_buf, "t%d", ins->dreg);
5111 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5113 if (ins->opcode == OP_VPHI)
5114 ctx->addresses [ins->dreg] = values [ins->dreg];
5116 g_ptr_array_add (phi_values, values [ins->dreg]);
5119 * Set the expected type of the incoming arguments since these have
5120 * to have the same type.
5122 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5123 int sreg1 = ins->inst_phi_args [i + 1];
5126 ctx->vreg_types [sreg1] = phi_type;
5131 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5140 * Create an ordering for bblocks, use the depth first order first, then
5141 * put the exception handling bblocks last.
5143 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5144 bb = cfg->bblocks [bb_index];
5145 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5146 g_ptr_array_add (bblock_list, bb);
5147 bblocks [bb->block_num].added = TRUE;
5151 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5152 if (!bblocks [bb->block_num].added)
5153 g_ptr_array_add (bblock_list, bb);
5157 * Second pass: generate code.
5159 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5160 bb = g_ptr_array_index (bblock_list, bb_index);
5162 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5165 process_bb (ctx, bb);
5166 CHECK_FAILURE (ctx);
5169 /* Add incoming phi values */
5170 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5171 GSList *l, *ins_list;
5173 ins_list = bblocks [bb->block_num].phi_nodes;
5175 for (l = ins_list; l; l = l->next) {
5176 PhiNode *node = l->data;
5177 MonoInst *phi = node->phi;
5178 int sreg1 = node->sreg;
5179 LLVMBasicBlockRef in_bb;
5184 in_bb = get_end_bb (ctx, node->in_bb);
5186 if (ctx->unreachable [node->in_bb->block_num])
5189 if (!values [sreg1])
5190 /* Can happen with values in EH clauses */
5191 LLVM_FAILURE (ctx, "incoming phi sreg1");
5193 if (phi->opcode == OP_VPHI) {
5194 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5195 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5197 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5199 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5200 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5201 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5206 /* Create the SWITCH statements for ENDFINALLY instructions */
5207 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5208 BBInfo *info = &bblocks [bb->block_num];
5210 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5211 LLVMValueRef switch_ins = l->data;
5212 GSList *bb_list = info->call_handler_return_bbs;
5214 for (i = 0; i < g_slist_length (bb_list); ++i)
5215 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5219 if (cfg->verbose_level > 1)
5220 mono_llvm_dump_value (method);
5222 if (cfg->compile_aot)
5223 mark_as_used (ctx->lmodule, method);
5225 if (cfg->compile_aot) {
5226 LLVMValueRef md_args [16];
5227 LLVMValueRef md_node;
5230 method_index = mono_aot_get_method_index (cfg->orig_method);
5231 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5232 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5233 md_node = LLVMMDNode (md_args, 2);
5234 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5235 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5238 if (cfg->compile_aot) {
5239 /* Don't generate native code, keep the LLVM IR */
5240 if (cfg->compile_aot && cfg->verbose_level)
5241 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5243 //LLVMVerifyFunction(method, 0);
5245 //LLVMVerifyFunction(method, 0);
5246 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5248 if (cfg->verbose_level > 1)
5249 mono_llvm_dump_value (method);
5251 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5253 /* Set by emit_cb */
5254 g_assert (cfg->code_len);
5256 /* FIXME: Free the LLVM IL for the function */
5259 if (ctx->lmodule->method_to_lmethod)
5260 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5267 /* Need to add unused phi nodes as they can be referenced by other values */
5268 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5269 LLVMBuilderRef builder;
5271 builder = create_builder (ctx);
5272 LLVMPositionBuilderAtEnd (builder, phi_bb);
5274 for (i = 0; i < phi_values->len; ++i) {
5275 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5276 if (LLVMGetInstructionParent (v) == NULL)
5277 LLVMInsertIntoBuilder (builder, v);
5280 LLVMDeleteFunction (method);
5285 g_free (ctx->addresses);
5286 g_free (ctx->vreg_types);
5287 g_free (ctx->vreg_cli_types);
5288 g_free (ctx->pindexes);
5289 g_free (ctx->is_dead);
5290 g_free (ctx->unreachable);
5291 g_ptr_array_free (phi_values, TRUE);
5292 g_free (ctx->bblocks);
5293 g_hash_table_destroy (ctx->region_to_handler);
5294 g_hash_table_destroy (ctx->clause_to_handler);
5295 g_free (method_name);
5296 g_ptr_array_free (bblock_list, TRUE);
5298 for (l = ctx->builders; l; l = l->next) {
5299 LLVMBuilderRef builder = l->data;
5300 LLVMDisposeBuilder (builder);
5305 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5307 mono_loader_unlock ();
5311 * mono_llvm_emit_call:
5313 * Same as mono_arch_emit_call () for LLVM.
5316 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5319 MonoMethodSignature *sig;
5320 int i, n, stack_size;
5325 sig = call->signature;
5326 n = sig->param_count + sig->hasthis;
5328 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5330 if (cfg->disable_llvm)
5333 if (sig->call_convention == MONO_CALL_VARARG) {
5334 cfg->exception_message = g_strdup ("varargs");
5335 cfg->disable_llvm = TRUE;
5338 for (i = 0; i < n; ++i) {
5341 ainfo = call->cinfo->args + i;
5343 in = call->args [i];
5345 /* Simply remember the arguments */
5346 switch (ainfo->storage) {
5348 case LLVMArgInFPReg: {
5349 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5352 opcode = mono_type_to_regmove (cfg, t);
5353 if (opcode == OP_FMOVE) {
5354 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5355 ins->dreg = mono_alloc_freg (cfg);
5356 } else if (opcode == OP_LMOVE) {
5357 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5358 ins->dreg = mono_alloc_lreg (cfg);
5360 MONO_INST_NEW (cfg, ins, OP_MOVE);
5361 ins->dreg = mono_alloc_ireg (cfg);
5363 ins->sreg1 = in->dreg;
5366 case LLVMArgVtypeByVal:
5367 case LLVMArgVtypeInReg:
5368 case LLVMArgAsIArgs:
5369 case LLVMArgAsFpArgs:
5370 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5371 ins->dreg = mono_alloc_ireg (cfg);
5372 ins->sreg1 = in->dreg;
5373 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5376 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5377 cfg->exception_message = g_strdup ("ainfo->storage");
5378 cfg->disable_llvm = TRUE;
5382 if (!cfg->disable_llvm) {
5383 MONO_ADD_INS (cfg->cbb, ins);
5384 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5389 static unsigned char*
5390 alloc_cb (LLVMValueRef function, int size)
5394 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5398 return mono_domain_code_reserve (cfg->domain, size);
5400 return mono_domain_code_reserve (mono_domain_get (), size);
5405 emitted_cb (LLVMValueRef function, void *start, void *end)
5409 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5411 cfg->code_len = (guint8*)end - (guint8*)start;
5415 exception_cb (void *data)
5418 MonoJitExceptionInfo *ei;
5419 guint32 ei_len, i, j, nested_len, nindex;
5420 gpointer *type_info;
5421 int this_reg, this_offset;
5423 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5427 * data points to a DWARF FDE structure, convert it to our unwind format and
5429 * An alternative would be to save it directly, and modify our unwinder to work
5432 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);
5433 if (cfg->verbose_level > 1)
5434 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5436 /* Count nested clauses */
5438 for (i = 0; i < ei_len; ++i) {
5439 gint32 cindex1 = *(gint32*)type_info [i];
5440 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5442 for (j = 0; j < cfg->header->num_clauses; ++j) {
5444 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5446 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5452 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5453 cfg->llvm_ex_info_len = ei_len + nested_len;
5454 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5455 /* Fill the rest of the information from the type info */
5456 for (i = 0; i < ei_len; ++i) {
5457 gint32 clause_index = *(gint32*)type_info [i];
5458 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5460 cfg->llvm_ex_info [i].flags = clause->flags;
5461 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5462 cfg->llvm_ex_info [i].clause_index = clause_index;
5466 * For nested clauses, the LLVM produced exception info associates the try interval with
5467 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5468 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5469 * and everything else from the nested clause.
5472 for (i = 0; i < ei_len; ++i) {
5473 gint32 cindex1 = *(gint32*)type_info [i];
5474 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5476 for (j = 0; j < cfg->header->num_clauses; ++j) {
5478 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5479 MonoJitExceptionInfo *nesting_ei, *nested_ei;
5481 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5482 /* clause1 is the nested clause */
5483 nested_ei = &cfg->llvm_ex_info [i];
5484 nesting_ei = &cfg->llvm_ex_info [nindex];
5487 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
5489 nesting_ei->flags = clause2->flags;
5490 nesting_ei->data.catch_class = clause2->data.catch_class;
5491 nesting_ei->clause_index = cindex2;
5495 g_assert (nindex == ei_len + nested_len);
5496 cfg->llvm_this_reg = this_reg;
5497 cfg->llvm_this_offset = this_offset;
5499 /* type_info [i] is cfg mempool allocated, no need to free it */
5506 dlsym_cb (const char *name, void **symbol)
5512 if (!strcmp (name, "__bzero")) {
5513 *symbol = (void*)bzero;
5515 current = mono_dl_open (NULL, 0, NULL);
5518 err = mono_dl_symbol (current, name, symbol);
5520 mono_dl_close (current);
5522 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5523 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5529 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5531 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5535 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5537 LLVMTypeRef param_types [4];
5539 param_types [0] = param_type1;
5540 param_types [1] = param_type2;
5542 AddFunc (module, name, ret_type, param_types, 2);
5546 add_intrinsics (LLVMModuleRef module)
5548 /* Emit declarations of instrinsics */
5550 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5551 * type doesn't seem to do any locking.
5554 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5556 memset_param_count = 5;
5557 memset_func_name = "llvm.memset.p0i8.i32";
5559 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5563 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5565 memcpy_param_count = 5;
5566 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5568 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5572 LLVMTypeRef params [] = { LLVMDoubleType () };
5574 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5575 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5576 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5578 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5579 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5583 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5584 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5585 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5587 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5588 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5589 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5590 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5591 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5592 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5593 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5597 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5598 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5599 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5601 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5602 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5603 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5604 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5605 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5606 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5611 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5613 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5616 /* SSE intrinsics */
5617 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5619 LLVMTypeRef ret_type, arg_types [16];
5622 ret_type = type_to_simd_type (MONO_TYPE_I4);
5623 arg_types [0] = ret_type;
5624 arg_types [1] = ret_type;
5625 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5626 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5628 ret_type = type_to_simd_type (MONO_TYPE_I2);
5629 arg_types [0] = ret_type;
5630 arg_types [1] = ret_type;
5631 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5633 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5639 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5640 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5642 ret_type = type_to_simd_type (MONO_TYPE_I1);
5643 arg_types [0] = ret_type;
5644 arg_types [1] = ret_type;
5645 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5647 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5648 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5649 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5650 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5651 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5653 ret_type = type_to_simd_type (MONO_TYPE_R8);
5654 arg_types [0] = ret_type;
5655 arg_types [1] = ret_type;
5656 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5657 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5658 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5659 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5660 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5662 ret_type = type_to_simd_type (MONO_TYPE_R4);
5663 arg_types [0] = ret_type;
5664 arg_types [1] = ret_type;
5665 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5666 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5667 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5668 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5669 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5672 ret_type = type_to_simd_type (MONO_TYPE_I1);
5673 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5674 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5675 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5676 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5677 ret_type = type_to_simd_type (MONO_TYPE_I2);
5678 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5679 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5680 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5681 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5684 ret_type = type_to_simd_type (MONO_TYPE_R8);
5685 arg_types [0] = ret_type;
5686 arg_types [1] = ret_type;
5687 arg_types [2] = LLVMInt8Type ();
5688 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5689 ret_type = type_to_simd_type (MONO_TYPE_R4);
5690 arg_types [0] = ret_type;
5691 arg_types [1] = ret_type;
5692 arg_types [2] = LLVMInt8Type ();
5693 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5695 /* Conversion ops */
5696 ret_type = type_to_simd_type (MONO_TYPE_R8);
5697 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5698 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5699 ret_type = type_to_simd_type (MONO_TYPE_R4);
5700 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5701 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5702 ret_type = type_to_simd_type (MONO_TYPE_I4);
5703 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5704 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5705 ret_type = type_to_simd_type (MONO_TYPE_I4);
5706 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5707 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5708 ret_type = type_to_simd_type (MONO_TYPE_R4);
5709 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5710 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5711 ret_type = type_to_simd_type (MONO_TYPE_R8);
5712 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5713 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5715 ret_type = type_to_simd_type (MONO_TYPE_I4);
5716 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5717 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5718 ret_type = type_to_simd_type (MONO_TYPE_I4);
5719 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5720 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5723 ret_type = type_to_simd_type (MONO_TYPE_R8);
5724 arg_types [0] = ret_type;
5725 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5726 ret_type = type_to_simd_type (MONO_TYPE_R4);
5727 arg_types [0] = ret_type;
5728 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5729 ret_type = type_to_simd_type (MONO_TYPE_R4);
5730 arg_types [0] = ret_type;
5731 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5732 ret_type = type_to_simd_type (MONO_TYPE_R4);
5733 arg_types [0] = ret_type;
5734 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5737 ret_type = type_to_simd_type (MONO_TYPE_I2);
5738 arg_types [0] = ret_type;
5739 arg_types [1] = LLVMInt32Type ();
5740 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5741 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5742 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5743 ret_type = type_to_simd_type (MONO_TYPE_I4);
5744 arg_types [0] = ret_type;
5745 arg_types [1] = LLVMInt32Type ();
5746 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5747 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5748 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5749 ret_type = type_to_simd_type (MONO_TYPE_I8);
5750 arg_types [0] = ret_type;
5751 arg_types [1] = LLVMInt32Type ();
5752 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5753 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5756 ret_type = LLVMInt32Type ();
5757 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5758 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5761 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5764 /* Load/Store intrinsics */
5766 LLVMTypeRef arg_types [5];
5770 for (i = 1; i <= 8; i *= 2) {
5771 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5772 arg_types [1] = LLVMInt32Type ();
5773 arg_types [2] = LLVMInt1Type ();
5774 arg_types [3] = LLVMInt32Type ();
5775 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5776 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5778 arg_types [0] = LLVMIntType (i * 8);
5779 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5780 arg_types [2] = LLVMInt32Type ();
5781 arg_types [3] = LLVMInt1Type ();
5782 arg_types [4] = LLVMInt32Type ();
5783 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5784 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5790 add_types (MonoLLVMModule *lmodule)
5792 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5796 mono_llvm_init (void)
5798 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5802 init_jit_module (MonoDomain *domain)
5804 MonoJitICallInfo *info;
5805 MonoJitDomainInfo *dinfo;
5806 MonoLLVMModule *module;
5809 dinfo = domain_jit_info (domain);
5810 if (dinfo->llvm_module)
5813 mono_loader_lock ();
5815 if (dinfo->llvm_module) {
5816 mono_loader_unlock ();
5820 module = g_new0 (MonoLLVMModule, 1);
5822 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5823 module->module = LLVMModuleCreateWithName (name);
5825 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5827 add_intrinsics (module->module);
5830 module->llvm_types = g_hash_table_new (NULL, NULL);
5832 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5834 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5836 mono_memory_barrier ();
5838 dinfo->llvm_module = module;
5840 mono_loader_unlock ();
5844 mono_llvm_cleanup (void)
5846 if (aot_module.module)
5847 LLVMDisposeModule (aot_module.module);
5849 LLVMContextDispose (LLVMGetGlobalContext ());
5853 mono_llvm_free_domain_info (MonoDomain *domain)
5855 MonoJitDomainInfo *info = domain_jit_info (domain);
5856 MonoLLVMModule *module = info->llvm_module;
5862 if (module->llvm_types)
5863 g_hash_table_destroy (module->llvm_types);
5865 mono_llvm_dispose_ee (module->mono_ee);
5867 if (module->bb_names) {
5868 for (i = 0; i < module->bb_names_len; ++i)
5869 g_free (module->bb_names [i]);
5870 g_free (module->bb_names);
5872 //LLVMDisposeModule (module->module);
5876 info->llvm_module = NULL;
5880 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link)
5882 MonoLLVMModule *lmodule = &aot_module;
5884 /* Delete previous module */
5885 if (lmodule->plt_entries)
5886 g_hash_table_destroy (lmodule->plt_entries);
5887 if (lmodule->module)
5888 LLVMDisposeModule (lmodule->module);
5890 memset (lmodule, 0, sizeof (aot_module));
5892 lmodule->module = LLVMModuleCreateWithName ("aot");
5893 lmodule->assembly = assembly;
5894 lmodule->global_prefix = g_strdup (global_prefix);
5895 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
5896 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
5897 lmodule->external_symbols = TRUE;
5898 lmodule->emit_dwarf = emit_dwarf;
5899 lmodule->static_link = static_link;
5900 /* The first few entries are reserved */
5901 lmodule->max_got_offset = 16;
5903 add_intrinsics (lmodule->module);
5904 add_types (lmodule);
5908 * We couldn't compute the type of the LLVM global representing the got because
5909 * its size is only known after all the methods have been emitted. So create
5910 * a dummy variable, and replace all uses it with the real got variable when
5911 * its size is known in mono_llvm_emit_aot_module ().
5914 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
5916 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
5917 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
5920 /* Add a dummy personality function */
5922 LLVMBasicBlockRef lbb;
5923 LLVMBuilderRef lbuilder;
5924 LLVMValueRef personality;
5926 personality = LLVMAddFunction (lmodule->module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5927 LLVMSetLinkage (personality, LLVMInternalLinkage);
5928 lbb = LLVMAppendBasicBlock (personality, "BB0");
5929 lbuilder = LLVMCreateBuilder ();
5930 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5931 LLVMBuildRetVoid (lbuilder);
5932 mark_as_used (lmodule, personality);
5935 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
5936 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5937 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
5938 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
5942 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
5945 LLVMValueRef res, *vals;
5947 vals = g_new0 (LLVMValueRef, nvalues);
5948 for (i = 0; i < nvalues; ++i)
5949 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
5950 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
5956 * mono_llvm_emit_aot_file_info:
5958 * Emit the MonoAotFileInfo structure.
5959 * Same as emit_aot_file_info () in aot-compiler.c.
5962 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
5964 MonoLLVMModule *lmodule = &aot_module;
5966 /* Save these for later */
5967 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
5968 lmodule->has_jitted_code = has_jitted_code;
5972 * mono_llvm_emit_aot_data:
5974 * Emit the binary data DATA pointed to by symbol SYMBOL.
5977 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
5979 MonoLLVMModule *lmodule = &aot_module;
5983 type = LLVMArrayType (LLVMInt8Type (), data_len);
5984 d = LLVMAddGlobal (lmodule->module, type, symbol);
5985 LLVMSetVisibility (d, LLVMHiddenVisibility);
5986 LLVMSetLinkage (d, LLVMInternalLinkage);
5987 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
5988 mono_llvm_set_is_constant (d);
5991 /* Add a reference to a global defined in JITted code */
5993 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
5998 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
5999 v = LLVMAddGlobal (lmodule->module, type, s);
6005 emit_aot_file_info (MonoLLVMModule *lmodule)
6007 LLVMTypeRef file_info_type;
6008 LLVMTypeRef *eltypes, eltype;
6009 LLVMValueRef info_var;
6010 LLVMValueRef *fields;
6011 int i, nfields, tindex;
6012 MonoAotFileInfo *info;
6014 info = &lmodule->aot_info;
6016 /* Create an LLVM type to represent MonoAotFileInfo */
6018 eltypes = g_new (LLVMTypeRef, nfields);
6020 eltypes [tindex ++] = LLVMInt32Type ();
6021 eltypes [tindex ++] = LLVMInt32Type ();
6023 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6024 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
6026 for (i = 0; i < 13; ++i)
6027 eltypes [tindex ++] = LLVMInt32Type ();
6029 for (i = 0; i < 4; ++i)
6030 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6031 g_assert (tindex == nfields);
6032 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6033 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6035 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
6036 if (lmodule->static_link) {
6037 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
6038 LLVMSetLinkage (info_var, LLVMInternalLinkage);
6040 fields = g_new (LLVMValueRef, nfields);
6042 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6043 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6047 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6048 * for symbols defined in the .s file emitted by the aot compiler.
6050 eltype = eltypes [tindex];
6051 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
6052 fields [tindex ++] = lmodule->got_var;
6053 /* llc defines this directly */
6054 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
6055 if (TRUE || lmodule->has_jitted_code) {
6056 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
6057 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
6058 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
6060 fields [tindex ++] = LLVMConstNull (eltype);
6061 fields [tindex ++] = LLVMConstNull (eltype);
6062 fields [tindex ++] = LLVMConstNull (eltype);
6064 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
6065 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
6066 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
6067 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
6068 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
6069 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
6070 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
6071 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
6072 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
6073 /* Not needed (mem_end) */
6074 fields [tindex ++] = LLVMConstNull (eltype);
6075 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
6076 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
6077 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
6078 if (info->trampoline_size [0]) {
6079 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
6080 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
6081 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
6082 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
6084 fields [tindex ++] = LLVMConstNull (eltype);
6085 fields [tindex ++] = LLVMConstNull (eltype);
6086 fields [tindex ++] = LLVMConstNull (eltype);
6087 fields [tindex ++] = LLVMConstNull (eltype);
6089 if (lmodule->static_link)
6090 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
6092 fields [tindex ++] = LLVMConstNull (eltype);
6093 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
6094 if (TRUE || lmodule->has_jitted_code) {
6095 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
6096 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
6097 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
6098 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
6099 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
6100 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
6102 fields [tindex ++] = LLVMConstNull (eltype);
6103 fields [tindex ++] = LLVMConstNull (eltype);
6104 fields [tindex ++] = LLVMConstNull (eltype);
6105 fields [tindex ++] = LLVMConstNull (eltype);
6106 fields [tindex ++] = LLVMConstNull (eltype);
6107 fields [tindex ++] = LLVMConstNull (eltype);
6111 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6112 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6113 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6114 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6115 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6116 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6117 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6118 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6119 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6120 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6121 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6122 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6123 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6125 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6126 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6127 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6128 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6129 g_assert (tindex == nfields);
6131 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6133 if (lmodule->static_link) {
6137 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
6138 /* Get rid of characters which cannot occur in symbols */
6140 for (p = s; *p; ++p) {
6141 if (!(isalnum (*p) || *p == '_'))
6144 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
6146 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
6147 LLVMSetLinkage (var, LLVMExternalLinkage);
6152 * Emit the aot module into the LLVM bitcode file FILENAME.
6155 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6157 LLVMTypeRef got_type;
6158 LLVMValueRef real_got;
6159 MonoLLVMModule *module = &aot_module;
6162 * Create the real got variable and replace all uses of the dummy variable with
6165 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6166 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6167 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6168 if (module->external_symbols) {
6169 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6170 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6172 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6174 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6176 mark_as_used (&aot_module, real_got);
6178 /* Delete the dummy got so it doesn't become a global */
6179 LLVMDeleteGlobal (aot_module.got_var);
6180 aot_module.got_var = real_got;
6182 emit_llvm_used (&aot_module);
6183 emit_dbg_info (&aot_module, filename, cu_name);
6184 emit_aot_file_info (&aot_module);
6186 /* Replace PLT entries for directly callable methods with the methods themselves */
6188 GHashTableIter iter;
6190 LLVMValueRef callee;
6192 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6193 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6194 if (mono_aot_is_direct_callable (ji)) {
6195 LLVMValueRef lmethod;
6197 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6198 /* The types might not match because the caller might pass an rgctx */
6199 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6200 mono_llvm_replace_uses_of (callee, lmethod);
6201 mono_aot_mark_unused_llvm_plt_entry (ji);
6211 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6212 g_assert_not_reached ();
6217 LLVMWriteBitcodeToFile (aot_module.module, filename);
6222 md_string (const char *s)
6224 return LLVMMDString (s, strlen (s));
6227 /* Debugging support */
6230 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6232 LLVMModuleRef module = lmodule->module;
6233 LLVMValueRef args [16], cu_args [16], cu, ver;
6235 char *build_info, *s, *dir;
6238 * This can only be enabled when LLVM code is emitted into a separate object
6239 * file, since the AOT compiler also emits dwarf info,
6240 * and the abbrev indexes will not be correct since llvm has added its own
6243 if (!lmodule->emit_dwarf)
6247 * Emit dwarf info in the form of LLVM metadata. There is some
6248 * out-of-date documentation at:
6249 * http://llvm.org/docs/SourceLevelDebugging.html
6250 * but most of this was gathered from the llvm and
6255 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6256 /* CU name/compilation dir */
6257 dir = g_path_get_dirname (filename);
6258 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6259 args [1] = LLVMMDString (dir, strlen (dir));
6260 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6263 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6265 build_info = mono_get_runtime_build_info ();
6266 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6267 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6268 g_free (build_info);
6270 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6272 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6273 /* Runtime version */
6274 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6276 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6277 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6279 if (lmodule->subprogram_mds) {
6283 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6284 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6285 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6286 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6288 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6291 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6292 /* Imported modules */
6293 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6295 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6296 /* DebugEmissionKind = FullDebug */
6297 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6298 cu = LLVMMDNode (cu_args, n_cuargs);
6299 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6301 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6302 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6303 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6304 ver = LLVMMDNode (args, 3);
6305 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6307 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6308 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6309 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6310 ver = LLVMMDNode (args, 3);
6311 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6315 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6317 MonoLLVMModule *module = ctx->lmodule;
6318 MonoDebugMethodInfo *minfo = ctx->minfo;
6319 char *source_file, *dir, *filename;
6320 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6321 MonoSymSeqPoint *sym_seq_points;
6327 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6329 source_file = g_strdup ("<unknown>");
6330 dir = g_path_get_dirname (source_file);
6331 filename = g_path_get_basename (source_file);
6333 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6334 args [0] = md_string (filename);
6335 args [1] = md_string (dir);
6336 ctx_args [1] = LLVMMDNode (args, 2);
6337 ctx_md = LLVMMDNode (ctx_args, 2);
6339 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6340 type_args [1] = NULL;
6341 type_args [2] = NULL;
6342 type_args [3] = LLVMMDString ("", 0);
6343 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6344 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6345 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6346 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6347 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6348 type_args [9] = NULL;
6349 type_args [10] = NULL;
6350 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6351 type_args [12] = NULL;
6352 type_args [13] = NULL;
6353 type_args [14] = NULL;
6354 type_md = LLVMMDNode (type_args, 14);
6356 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6357 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6358 /* Source directory + file pair */
6359 args [0] = md_string (filename);
6360 args [1] = md_string (dir);
6361 md_args [1] = LLVMMDNode (args ,2);
6362 md_args [2] = ctx_md;
6363 md_args [3] = md_string (cfg->method->name);
6364 md_args [4] = md_string (name);
6365 md_args [5] = md_string (name);
6368 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6370 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6372 md_args [7] = type_md;
6374 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6376 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6378 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6379 /* Index into a virtual function */
6380 md_args [11] = NULL;
6381 md_args [12] = NULL;
6383 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6385 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6386 /* Pointer to LLVM function */
6387 md_args [15] = method;
6388 /* Function template parameter */
6389 md_args [16] = NULL;
6390 /* Function declaration descriptor */
6391 md_args [17] = NULL;
6392 /* List of function variables */
6393 md_args [18] = LLVMMDNode (args, 0);
6395 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6396 md = LLVMMDNode (md_args, 20);
6398 if (!module->subprogram_mds)
6399 module->subprogram_mds = g_ptr_array_new ();
6400 g_ptr_array_add (module->subprogram_mds, md);
6404 g_free (source_file);
6405 g_free (sym_seq_points);
6411 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6413 MonoCompile *cfg = ctx->cfg;
6415 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6416 MonoDebugSourceLocation *loc;
6417 LLVMValueRef loc_md, md_args [16];
6420 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6424 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6425 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6426 md_args [nmd_args ++] = ctx->dbg_md;
6427 md_args [nmd_args ++] = NULL;
6428 loc_md = LLVMMDNode (md_args, nmd_args);
6429 LLVMSetCurrentDebugLocation (builder, loc_md);
6430 mono_debug_symfile_free_location (loc);
6437 - Emit LLVM IR from the mono IR using the LLVM C API.
6438 - The original arch specific code remains, so we can fall back to it if we run
6439 into something we can't handle.
6443 A partial list of issues:
6444 - Handling of opcodes which can throw exceptions.
6446 In the mono JIT, these are implemented using code like this:
6453 push throw_pos - method
6454 call <exception trampoline>
6456 The problematic part is push throw_pos - method, which cannot be represented
6457 in the LLVM IR, since it does not support label values.
6458 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6459 be implemented in JIT mode ?
6460 -> a possible but slower implementation would use the normal exception
6461 throwing code but it would need to control the placement of the throw code
6462 (it needs to be exactly after the compare+branch).
6463 -> perhaps add a PC offset intrinsics ?
6465 - efficient implementation of .ovf opcodes.
6467 These are currently implemented as:
6468 <ins which sets the condition codes>
6471 Some overflow opcodes are now supported by LLVM SVN.
6473 - exception handling, unwinding.
6474 - SSA is disabled for methods with exception handlers
6475 - How to obtain unwind info for LLVM compiled methods ?
6476 -> this is now solved by converting the unwind info generated by LLVM
6478 - LLVM uses the c++ exception handling framework, while we use our home grown
6479 code, and couldn't use the c++ one:
6480 - its not supported under VC++, other exotic platforms.
6481 - it might be impossible to support filter clauses with it.
6485 The trampolines need a predictable call sequence, since they need to disasm
6486 the calling code to obtain register numbers / offsets.
6488 LLVM currently generates this code in non-JIT mode:
6489 mov -0x98(%rax),%eax
6491 Here, the vtable pointer is lost.
6492 -> solution: use one vtable trampoline per class.
6494 - passing/receiving the IMT pointer/RGCTX.
6495 -> solution: pass them as normal arguments ?
6499 LLVM does not allow the specification of argument registers etc. This means
6500 that all calls are made according to the platform ABI.
6502 - passing/receiving vtypes.
6504 Vtypes passed/received in registers are handled by the front end by using
6505 a signature with scalar arguments, and loading the parts of the vtype into those
6508 Vtypes passed on the stack are handled using the 'byval' attribute.
6512 Supported though alloca, we need to emit the load/store code.
6516 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6517 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6518 This is made easier because the IR is already in SSA form.
6519 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6520 types are frequently used incorrectly.
6525 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6526 it with the file containing the methods emitted by the JIT and the AOT data
6530 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6531 * - each bblock should end with a branch
6532 * - setting the return value, making cfg->ret non-volatile
6533 * - avoid some transformations in the JIT which make it harder for us to generate
6535 * - use pointer types to help optimizations.