2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 LLVMValueRef generic_class_init_tramp;
50 GHashTable *llvm_types;
52 const char *got_symbol;
53 GHashTable *plt_entries;
54 GHashTable *plt_entries_ji;
55 GHashTable *method_to_lmethod;
60 GPtrArray *subprogram_mds;
62 LLVMExecutionEngineRef ee;
63 gboolean external_symbols;
68 MonoAssembly *assembly;
70 MonoAotFileInfo aot_info;
71 const char *jit_got_symbol;
72 const char *eh_frame_symbol;
73 LLVMValueRef code_start, code_end;
74 gboolean has_jitted_code;
79 * Information associated by the backend with mono basic blocks.
82 LLVMBasicBlockRef bblock, end_bblock;
83 LLVMValueRef finally_ind;
84 gboolean added, invoke_target;
86 * If this bblock is the start of a finally clause, this is a list of bblocks it
87 * needs to branch to in ENDFINALLY.
89 GSList *call_handler_return_bbs;
91 * If this bblock is the start of a finally clause, this is the bblock that
92 * CALL_HANDLER needs to branch to.
94 LLVMBasicBlockRef call_handler_target_bb;
95 /* The list of switch statements generated by ENDFINALLY instructions */
96 GSList *endfinally_switch_ins_list;
101 * Structure containing emit state
104 MonoMemPool *mempool;
106 /* Maps method names to the corresponding LLVMValueRef */
107 GHashTable *emitted_method_decls;
110 LLVMValueRef lmethod;
111 MonoLLVMModule *lmodule;
112 LLVMModuleRef module;
114 int sindex, default_index, ex_index;
115 LLVMBuilderRef builder;
116 LLVMValueRef *values, *addresses;
117 MonoType **vreg_cli_types;
119 MonoMethodSignature *sig;
121 GHashTable *region_to_handler;
122 GHashTable *clause_to_handler;
123 LLVMBuilderRef alloca_builder;
124 LLVMValueRef last_alloca;
125 LLVMValueRef rgctx_arg;
126 LLVMTypeRef *vreg_types;
128 gboolean *unreachable;
130 LLVMValueRef imt_rgctx_loc;
131 GHashTable *llvm_types;
133 MonoDebugMethodInfo *minfo;
135 /* For every clause, the clauses it is nested in */
143 MonoBasicBlock *in_bb;
148 * Instruction metadata
149 * This is the same as ins_info, but LREG != IREG.
157 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
158 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
165 /* keep in sync with the enum in mini.h */
168 #include "mini-ops.h"
173 #if SIZEOF_VOID_P == 4
174 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
176 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
179 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
182 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
184 #define TRACE_FAILURE(msg)
188 #define IS_TARGET_X86 1
190 #define IS_TARGET_X86 0
194 #define IS_TARGET_AMD64 1
196 #define IS_TARGET_AMD64 0
199 #define LLVM_FAILURE(ctx, reason) do { \
200 TRACE_FAILURE (reason); \
201 (ctx)->cfg->exception_message = g_strdup (reason); \
202 (ctx)->cfg->disable_llvm = TRUE; \
206 #define CHECK_FAILURE(ctx) do { \
207 if ((ctx)->cfg->disable_llvm) \
211 static LLVMIntPredicate cond_to_llvm_cond [] = {
224 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
237 static MonoNativeTlsKey current_cfg_tls_id;
239 static MonoLLVMModule aot_module;
240 static int memset_param_count, memcpy_param_count;
241 static const char *memset_func_name;
242 static const char *memcpy_func_name;
244 static void init_jit_module (MonoDomain *domain);
246 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
247 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
248 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
253 * The LLVM type with width == sizeof (gpointer)
258 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
264 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
270 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
276 * Return the size of the LLVM representation of the vtype T.
279 get_vtype_size (MonoType *t)
283 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
285 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
292 * simd_class_to_llvm_type:
294 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
297 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
299 if (!strcmp (klass->name, "Vector2d")) {
300 return LLVMVectorType (LLVMDoubleType (), 2);
301 } else if (!strcmp (klass->name, "Vector2l")) {
302 return LLVMVectorType (LLVMInt64Type (), 2);
303 } else if (!strcmp (klass->name, "Vector2ul")) {
304 return LLVMVectorType (LLVMInt64Type (), 2);
305 } else if (!strcmp (klass->name, "Vector4i")) {
306 return LLVMVectorType (LLVMInt32Type (), 4);
307 } else if (!strcmp (klass->name, "Vector4ui")) {
308 return LLVMVectorType (LLVMInt32Type (), 4);
309 } else if (!strcmp (klass->name, "Vector4f")) {
310 return LLVMVectorType (LLVMFloatType (), 4);
311 } else if (!strcmp (klass->name, "Vector8s")) {
312 return LLVMVectorType (LLVMInt16Type (), 8);
313 } else if (!strcmp (klass->name, "Vector8us")) {
314 return LLVMVectorType (LLVMInt16Type (), 8);
315 } else if (!strcmp (klass->name, "Vector16sb")) {
316 return LLVMVectorType (LLVMInt8Type (), 16);
317 } else if (!strcmp (klass->name, "Vector16b")) {
318 return LLVMVectorType (LLVMInt8Type (), 16);
320 printf ("%s\n", klass->name);
326 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
327 static inline G_GNUC_UNUSED LLVMTypeRef
328 type_to_simd_type (int type)
332 return LLVMVectorType (LLVMInt8Type (), 16);
334 return LLVMVectorType (LLVMInt16Type (), 8);
336 return LLVMVectorType (LLVMInt32Type (), 4);
338 return LLVMVectorType (LLVMInt64Type (), 2);
340 return LLVMVectorType (LLVMDoubleType (), 2);
342 return LLVMVectorType (LLVMFloatType (), 4);
344 g_assert_not_reached ();
350 create_llvm_type_for_type (MonoClass *klass)
352 int i, size, nfields, esize;
353 LLVMTypeRef *eltypes;
358 t = &klass->byval_arg;
360 if (mini_type_is_hfa (t, &nfields, &esize)) {
362 * This is needed on arm64 where HFAs are returned in
366 eltypes = g_new (LLVMTypeRef, size);
367 for (i = 0; i < size; ++i)
368 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
370 size = get_vtype_size (t);
372 eltypes = g_new (LLVMTypeRef, size);
373 for (i = 0; i < size; ++i)
374 eltypes [i] = LLVMInt8Type ();
377 name = mono_type_full_name (&klass->byval_arg);
378 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
379 LLVMStructSetBody (ltype, eltypes, size, FALSE);
389 * Return the LLVM type corresponding to T.
392 type_to_llvm_type (EmitContext *ctx, MonoType *t)
395 return LLVMPointerType (LLVMInt8Type (), 0);
397 t = mini_get_underlying_type (ctx->cfg, t);
400 return LLVMVoidType ();
402 return LLVMInt8Type ();
404 return LLVMInt16Type ();
406 return LLVMInt32Type ();
408 return LLVMInt8Type ();
410 return LLVMInt16Type ();
412 return LLVMInt32Type ();
413 case MONO_TYPE_BOOLEAN:
414 return LLVMInt8Type ();
417 return LLVMInt64Type ();
419 return LLVMInt16Type ();
421 return LLVMFloatType ();
423 return LLVMDoubleType ();
426 return IntPtrType ();
427 case MONO_TYPE_OBJECT:
428 case MONO_TYPE_CLASS:
429 case MONO_TYPE_ARRAY:
430 case MONO_TYPE_SZARRAY:
431 case MONO_TYPE_STRING:
433 return ObjRefType ();
436 /* Because of generic sharing */
437 return ObjRefType ();
438 case MONO_TYPE_GENERICINST:
439 if (!mono_type_generic_inst_is_valuetype (t))
440 return ObjRefType ();
442 case MONO_TYPE_VALUETYPE:
443 case MONO_TYPE_TYPEDBYREF: {
447 klass = mono_class_from_mono_type (t);
449 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
450 return simd_class_to_llvm_type (ctx, klass);
453 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
455 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
457 ltype = create_llvm_type_for_type (klass);
458 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
464 printf ("X: %d\n", t->type);
465 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
466 ctx->cfg->disable_llvm = TRUE;
474 * Return whenever T is an unsigned int type.
477 type_is_unsigned (EmitContext *ctx, MonoType *t)
494 * type_to_llvm_arg_type:
496 * Same as type_to_llvm_type, but treat i8/i16 as i32.
499 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
501 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
504 * This works on all abis except arm64/ios which passes multiple
505 * arguments in one stack slot.
508 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
510 * LLVM generates code which only sets the lower bits, while JITted
511 * code expects all the bits to be set.
513 ptype = LLVMInt32Type ();
521 * llvm_type_to_stack_type:
523 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
526 static G_GNUC_UNUSED LLVMTypeRef
527 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
531 if (type == LLVMInt8Type ())
532 return LLVMInt32Type ();
533 else if (type == LLVMInt16Type ())
534 return LLVMInt32Type ();
535 else if (!cfg->r4fp && type == LLVMFloatType ())
536 return LLVMDoubleType ();
542 * regtype_to_llvm_type:
544 * Return the LLVM type corresponding to the regtype C used in instruction
548 regtype_to_llvm_type (char c)
552 return LLVMInt32Type ();
554 return LLVMInt64Type ();
556 return LLVMDoubleType ();
565 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
568 op_to_llvm_type (int opcode)
573 return LLVMInt8Type ();
576 return LLVMInt8Type ();
579 return LLVMInt16Type ();
582 return LLVMInt16Type ();
585 return LLVMInt32Type ();
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
592 return LLVMFloatType ();
594 return LLVMDoubleType ();
596 return LLVMInt64Type ();
598 return LLVMInt32Type ();
600 return LLVMInt64Type ();
605 return LLVMInt8Type ();
610 return LLVMInt16Type ();
613 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
620 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 printf ("%s\n", mono_inst_name (opcode));
630 g_assert_not_reached ();
636 * load_store_to_llvm_type:
638 * Return the size/sign/zero extension corresponding to the load/store opcode
642 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
648 case OP_LOADI1_MEMBASE:
649 case OP_STOREI1_MEMBASE_REG:
650 case OP_STOREI1_MEMBASE_IMM:
651 case OP_ATOMIC_LOAD_I1:
652 case OP_ATOMIC_STORE_I1:
655 return LLVMInt8Type ();
656 case OP_LOADU1_MEMBASE:
658 case OP_ATOMIC_LOAD_U1:
659 case OP_ATOMIC_STORE_U1:
662 return LLVMInt8Type ();
663 case OP_LOADI2_MEMBASE:
664 case OP_STOREI2_MEMBASE_REG:
665 case OP_STOREI2_MEMBASE_IMM:
666 case OP_ATOMIC_LOAD_I2:
667 case OP_ATOMIC_STORE_I2:
670 return LLVMInt16Type ();
671 case OP_LOADU2_MEMBASE:
673 case OP_ATOMIC_LOAD_U2:
674 case OP_ATOMIC_STORE_U2:
677 return LLVMInt16Type ();
678 case OP_LOADI4_MEMBASE:
679 case OP_LOADU4_MEMBASE:
682 case OP_STOREI4_MEMBASE_REG:
683 case OP_STOREI4_MEMBASE_IMM:
684 case OP_ATOMIC_LOAD_I4:
685 case OP_ATOMIC_STORE_I4:
686 case OP_ATOMIC_LOAD_U4:
687 case OP_ATOMIC_STORE_U4:
689 return LLVMInt32Type ();
690 case OP_LOADI8_MEMBASE:
692 case OP_STOREI8_MEMBASE_REG:
693 case OP_STOREI8_MEMBASE_IMM:
694 case OP_ATOMIC_LOAD_I8:
695 case OP_ATOMIC_STORE_I8:
696 case OP_ATOMIC_LOAD_U8:
697 case OP_ATOMIC_STORE_U8:
699 return LLVMInt64Type ();
700 case OP_LOADR4_MEMBASE:
701 case OP_STORER4_MEMBASE_REG:
702 case OP_ATOMIC_LOAD_R4:
703 case OP_ATOMIC_STORE_R4:
705 return LLVMFloatType ();
706 case OP_LOADR8_MEMBASE:
707 case OP_STORER8_MEMBASE_REG:
708 case OP_ATOMIC_LOAD_R8:
709 case OP_ATOMIC_STORE_R8:
711 return LLVMDoubleType ();
712 case OP_LOAD_MEMBASE:
714 case OP_STORE_MEMBASE_REG:
715 case OP_STORE_MEMBASE_IMM:
716 *size = sizeof (gpointer);
717 return IntPtrType ();
719 g_assert_not_reached ();
727 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
730 ovf_op_to_intrins (int opcode)
734 return "llvm.sadd.with.overflow.i32";
736 return "llvm.uadd.with.overflow.i32";
738 return "llvm.ssub.with.overflow.i32";
740 return "llvm.usub.with.overflow.i32";
742 return "llvm.smul.with.overflow.i32";
744 return "llvm.umul.with.overflow.i32";
746 return "llvm.sadd.with.overflow.i64";
748 return "llvm.uadd.with.overflow.i64";
750 return "llvm.ssub.with.overflow.i64";
752 return "llvm.usub.with.overflow.i64";
754 return "llvm.smul.with.overflow.i64";
756 return "llvm.umul.with.overflow.i64";
758 g_assert_not_reached ();
764 simd_op_to_intrins (int opcode)
767 #if defined(TARGET_X86) || defined(TARGET_AMD64)
769 return "llvm.x86.sse2.min.pd";
771 return "llvm.x86.sse.min.ps";
773 return "llvm.x86.sse41.pminud";
775 return "llvm.x86.sse41.pminuw";
777 return "llvm.x86.sse2.pminu.b";
779 return "llvm.x86.sse2.pmins.w";
781 return "llvm.x86.sse2.max.pd";
783 return "llvm.x86.sse.max.ps";
785 return "llvm.x86.sse3.hadd.pd";
787 return "llvm.x86.sse3.hadd.ps";
789 return "llvm.x86.sse3.hsub.pd";
791 return "llvm.x86.sse3.hsub.ps";
793 return "llvm.x86.sse41.pmaxud";
795 return "llvm.x86.sse41.pmaxuw";
797 return "llvm.x86.sse2.pmaxu.b";
799 return "llvm.x86.sse3.addsub.ps";
801 return "llvm.x86.sse3.addsub.pd";
802 case OP_EXTRACT_MASK:
803 return "llvm.x86.sse2.pmovmskb.128";
806 return "llvm.x86.sse2.psrli.w";
809 return "llvm.x86.sse2.psrli.d";
812 return "llvm.x86.sse2.psrli.q";
815 return "llvm.x86.sse2.pslli.w";
818 return "llvm.x86.sse2.pslli.d";
821 return "llvm.x86.sse2.pslli.q";
824 return "llvm.x86.sse2.psrai.w";
827 return "llvm.x86.sse2.psrai.d";
829 return "llvm.x86.sse2.padds.b";
831 return "llvm.x86.sse2.padds.w";
833 return "llvm.x86.sse2.psubs.b";
835 return "llvm.x86.sse2.psubs.w";
836 case OP_PADDB_SAT_UN:
837 return "llvm.x86.sse2.paddus.b";
838 case OP_PADDW_SAT_UN:
839 return "llvm.x86.sse2.paddus.w";
840 case OP_PSUBB_SAT_UN:
841 return "llvm.x86.sse2.psubus.b";
842 case OP_PSUBW_SAT_UN:
843 return "llvm.x86.sse2.psubus.w";
845 return "llvm.x86.sse2.pavg.b";
847 return "llvm.x86.sse2.pavg.w";
849 return "llvm.x86.sse.sqrt.ps";
851 return "llvm.x86.sse2.sqrt.pd";
853 return "llvm.x86.sse.rsqrt.ps";
855 return "llvm.x86.sse.rcp.ps";
857 return "llvm.x86.sse2.cvtdq2pd";
859 return "llvm.x86.sse2.cvtdq2ps";
861 return "llvm.x86.sse2.cvtpd2dq";
863 return "llvm.x86.sse2.cvtps2dq";
865 return "llvm.x86.sse2.cvtpd2ps";
867 return "llvm.x86.sse2.cvtps2pd";
869 return "llvm.x86.sse2.cvttpd2dq";
871 return "llvm.x86.sse2.cvttps2dq";
873 return "llvm.x86.sse.cmp.ps";
875 return "llvm.x86.sse2.cmp.pd";
877 return "llvm.x86.sse2.packsswb.128";
879 return "llvm.x86.sse2.packssdw.128";
881 return "llvm.x86.sse2.packuswb.128";
883 return "llvm.x86.sse41.packusdw";
885 return "llvm.x86.sse2.pmulh.w";
886 case OP_PMULW_HIGH_UN:
887 return "llvm.x86.sse2.pmulhu.w";
890 g_assert_not_reached ();
896 simd_op_to_llvm_type (int opcode)
898 #if defined(TARGET_X86) || defined(TARGET_AMD64)
902 return type_to_simd_type (MONO_TYPE_R8);
905 return type_to_simd_type (MONO_TYPE_I8);
908 return type_to_simd_type (MONO_TYPE_I4);
913 return type_to_simd_type (MONO_TYPE_I2);
917 return type_to_simd_type (MONO_TYPE_I1);
919 return type_to_simd_type (MONO_TYPE_R4);
922 return type_to_simd_type (MONO_TYPE_I4);
926 return type_to_simd_type (MONO_TYPE_R8);
930 return type_to_simd_type (MONO_TYPE_R4);
931 case OP_EXTRACT_MASK:
932 return type_to_simd_type (MONO_TYPE_I1);
938 return type_to_simd_type (MONO_TYPE_R4);
941 return type_to_simd_type (MONO_TYPE_R8);
943 g_assert_not_reached ();
954 * Return the LLVM basic block corresponding to BB.
956 static LLVMBasicBlockRef
957 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
959 char bb_name_buf [128];
962 if (ctx->bblocks [bb->block_num].bblock == NULL) {
963 if (bb->flags & BB_EXCEPTION_HANDLER) {
964 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
965 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
966 bb_name = bb_name_buf;
967 } else if (bb->block_num < 256) {
968 if (!ctx->lmodule->bb_names) {
969 ctx->lmodule->bb_names_len = 256;
970 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
972 if (!ctx->lmodule->bb_names [bb->block_num]) {
975 n = g_strdup_printf ("BB%d", bb->block_num);
976 mono_memory_barrier ();
977 ctx->lmodule->bb_names [bb->block_num] = n;
979 bb_name = ctx->lmodule->bb_names [bb->block_num];
981 sprintf (bb_name_buf, "BB%d", bb->block_num);
982 bb_name = bb_name_buf;
985 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
986 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
989 return ctx->bblocks [bb->block_num].bblock;
995 * Return the last LLVM bblock corresponding to BB.
996 * This might not be equal to the bb returned by get_bb () since we need to generate
997 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
999 static LLVMBasicBlockRef
1000 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1003 return ctx->bblocks [bb->block_num].end_bblock;
1006 static LLVMBasicBlockRef
1007 gen_bb (EmitContext *ctx, const char *prefix)
1011 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1012 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1018 * Return the target of the patch identified by TYPE and TARGET.
1021 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1025 memset (&ji, 0, sizeof (ji));
1027 ji.data.target = target;
1029 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1035 * Emit code to convert the LLVM value V to DTYPE.
1038 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1040 LLVMTypeRef stype = LLVMTypeOf (v);
1042 if (stype != dtype) {
1043 gboolean ext = FALSE;
1046 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1048 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1050 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1054 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1056 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1057 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1060 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1061 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1062 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1063 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1064 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1065 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1066 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1067 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1069 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1070 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1071 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1072 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1073 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1074 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1076 if (mono_arch_is_soft_float ()) {
1077 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1078 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1079 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1080 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1083 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1084 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1087 LLVMDumpValue (LLVMConstNull (dtype));
1088 g_assert_not_reached ();
1096 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1098 return convert_full (ctx, v, dtype, FALSE);
1102 * emit_volatile_load:
1104 * If vreg is volatile, emit a load from its address.
1107 emit_volatile_load (EmitContext *ctx, int vreg)
1111 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1112 t = ctx->vreg_cli_types [vreg];
1113 if (t && !t->byref) {
1115 * Might have to zero extend since llvm doesn't have
1118 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1119 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1120 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1121 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1122 else if (t->type == MONO_TYPE_U8)
1123 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1130 * emit_volatile_store:
1132 * If VREG is volatile, emit a store from its value to its address.
1135 emit_volatile_store (EmitContext *ctx, int vreg)
1137 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1139 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1140 g_assert (ctx->addresses [vreg]);
1141 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1147 * Maps parameter indexes in the original signature to parameter indexes
1148 * in the LLVM signature.
1151 /* The indexes of various special arguments in the LLVM signature */
1152 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1156 * sig_to_llvm_sig_full:
1158 * Return the LLVM signature corresponding to the mono signature SIG using the
1159 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1162 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1165 LLVMTypeRef ret_type;
1166 LLVMTypeRef *param_types = NULL;
1168 int i, j, pindex, vret_arg_pindex = 0;
1170 gboolean vretaddr = FALSE;
1174 memset (sinfo, 0, sizeof (LLVMSigInfo));
1176 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1177 ret_type = type_to_llvm_type (ctx, rtype);
1178 CHECK_FAILURE (ctx);
1181 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1182 /* LLVM models this by returning an aggregate value */
1183 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1184 LLVMTypeRef members [2];
1186 members [0] = IntPtrType ();
1187 ret_type = LLVMStructType (members, 1, FALSE);
1189 g_assert_not_reached ();
1191 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1192 /* Vtype returned normally by val */
1193 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1194 /* Vtype returned as a fp struct */
1195 LLVMTypeRef members [16];
1197 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1198 for (i = 0; i < cinfo->ret.nslots; ++i)
1199 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1200 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1201 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1202 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1204 ret_type = LLVMVoidType ();
1208 pindexes = g_new0 (int, sig->param_count);
1209 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1211 if (cinfo && cinfo->rgctx_arg) {
1213 sinfo->rgctx_arg_pindex = pindex;
1214 param_types [pindex] = ctx->lmodule->ptr_type;
1217 if (cinfo && cinfo->imt_arg) {
1219 sinfo->imt_arg_pindex = pindex;
1220 param_types [pindex] = ctx->lmodule->ptr_type;
1224 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1225 vret_arg_pindex = pindex;
1226 if (cinfo->vret_arg_index == 1) {
1227 /* Add the slots consumed by the first argument */
1228 LLVMArgInfo *ainfo = &cinfo->args [0];
1229 switch (ainfo->storage) {
1230 case LLVMArgVtypeInReg:
1231 for (j = 0; j < 2; ++j) {
1232 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1242 sinfo->vret_arg_pindex = vret_arg_pindex;
1245 if (vretaddr && vret_arg_pindex == pindex)
1246 param_types [pindex ++] = IntPtrType ();
1249 sinfo->this_arg_pindex = pindex;
1250 param_types [pindex ++] = ThisType ();
1252 if (vretaddr && vret_arg_pindex == pindex)
1253 param_types [pindex ++] = IntPtrType ();
1254 for (i = 0; i < sig->param_count; ++i) {
1255 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1257 if (vretaddr && vret_arg_pindex == pindex)
1258 param_types [pindex ++] = IntPtrType ();
1259 pindexes [i] = pindex;
1262 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1266 switch (ainfo->storage) {
1267 case LLVMArgVtypeInReg:
1268 for (j = 0; j < 2; ++j) {
1269 switch (ainfo->pair_storage [j]) {
1271 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1276 g_assert_not_reached ();
1280 case LLVMArgVtypeByVal:
1281 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1282 CHECK_FAILURE (ctx);
1283 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1286 case LLVMArgAsIArgs:
1287 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1290 case LLVMArgAsFpArgs: {
1293 for (j = 0; j < ainfo->nslots; ++j)
1294 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1295 pindex += ainfo->nslots;
1299 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1303 if (vretaddr && vret_arg_pindex == pindex)
1304 param_types [pindex ++] = IntPtrType ();
1306 CHECK_FAILURE (ctx);
1308 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1309 g_free (param_types);
1312 sinfo->pindexes = pindexes;
1320 g_free (param_types);
1326 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1328 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1332 * LLVMFunctionType1:
1334 * Create an LLVM function type from the arguments.
1336 static G_GNUC_UNUSED LLVMTypeRef
1337 LLVMFunctionType1(LLVMTypeRef ReturnType,
1338 LLVMTypeRef ParamType1,
1341 LLVMTypeRef param_types [1];
1343 param_types [0] = ParamType1;
1345 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1349 * LLVMFunctionType2:
1351 * Create an LLVM function type from the arguments.
1353 static G_GNUC_UNUSED LLVMTypeRef
1354 LLVMFunctionType2(LLVMTypeRef ReturnType,
1355 LLVMTypeRef ParamType1,
1356 LLVMTypeRef ParamType2,
1359 LLVMTypeRef param_types [2];
1361 param_types [0] = ParamType1;
1362 param_types [1] = ParamType2;
1364 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1368 * LLVMFunctionType3:
1370 * Create an LLVM function type from the arguments.
1372 static G_GNUC_UNUSED LLVMTypeRef
1373 LLVMFunctionType3(LLVMTypeRef ReturnType,
1374 LLVMTypeRef ParamType1,
1375 LLVMTypeRef ParamType2,
1376 LLVMTypeRef ParamType3,
1379 LLVMTypeRef param_types [3];
1381 param_types [0] = ParamType1;
1382 param_types [1] = ParamType2;
1383 param_types [2] = ParamType3;
1385 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1391 * Create an LLVM builder and remember it so it can be freed later.
1393 static LLVMBuilderRef
1394 create_builder (EmitContext *ctx)
1396 LLVMBuilderRef builder = LLVMCreateBuilder ();
1398 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1404 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1406 char *callee_name = mono_aot_get_plt_symbol (type, data);
1407 LLVMValueRef callee;
1408 MonoJumpInfo *ji = NULL;
1413 if (ctx->cfg->compile_aot)
1414 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1415 mono_add_patch_info (ctx->cfg, 0, type, data);
1418 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1420 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1422 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1424 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1427 if (ctx->cfg->compile_aot) {
1428 ji = g_new0 (MonoJumpInfo, 1);
1430 ji->data.target = data;
1432 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1439 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1441 MonoMethodHeader *header = cfg->header;
1442 MonoExceptionClause *clause;
1446 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1447 return (bb->region >> 8) - 1;
1450 for (i = 0; i < header->num_clauses; ++i) {
1451 clause = &header->clauses [i];
1453 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1461 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1463 LLVMValueRef md_arg;
1466 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1467 md_arg = LLVMMDString ("mono", 4);
1468 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1472 set_invariant_load_flag (LLVMValueRef v)
1474 LLVMValueRef md_arg;
1476 const char *flag_name;
1478 // FIXME: Cache this
1479 flag_name = "invariant.load";
1480 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1481 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1482 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1488 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1492 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1494 MonoCompile *cfg = ctx->cfg;
1496 LLVMBuilderRef builder = *builder_ref;
1499 clause_index = get_handler_clause (cfg, bb);
1501 if (clause_index != -1) {
1502 MonoMethodHeader *header = cfg->header;
1503 MonoExceptionClause *ec = &header->clauses [clause_index];
1504 MonoBasicBlock *tblock;
1505 LLVMBasicBlockRef ex_bb, noex_bb;
1508 * Have to use an invoke instead of a call, branching to the
1509 * handler bblock of the clause containing this bblock.
1512 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1514 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1517 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1519 ex_bb = get_bb (ctx, tblock);
1521 noex_bb = gen_bb (ctx, "NOEX_BB");
1524 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1526 builder = ctx->builder = create_builder (ctx);
1527 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1529 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1531 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1532 ctx->builder = builder;
1535 *builder_ref = ctx->builder;
1541 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1543 const char *intrins_name;
1544 LLVMValueRef args [16], res;
1545 LLVMTypeRef addr_type;
1547 if (is_faulting && bb->region != -1) {
1548 LLVMAtomicOrdering ordering;
1551 case LLVM_BARRIER_NONE:
1552 ordering = LLVMAtomicOrderingNotAtomic;
1554 case LLVM_BARRIER_ACQ:
1555 ordering = LLVMAtomicOrderingAcquire;
1557 case LLVM_BARRIER_SEQ:
1558 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1561 g_assert_not_reached ();
1566 * We handle loads which can fault by calling a mono specific intrinsic
1567 * using an invoke, so they are handled properly inside try blocks.
1568 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1569 * are marked with IntrReadArgMem.
1573 intrins_name = "llvm.mono.load.i8.p0i8";
1576 intrins_name = "llvm.mono.load.i16.p0i16";
1579 intrins_name = "llvm.mono.load.i32.p0i32";
1582 intrins_name = "llvm.mono.load.i64.p0i64";
1585 g_assert_not_reached ();
1588 addr_type = LLVMTypeOf (addr);
1589 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1590 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1593 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1594 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1595 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1596 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1598 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1599 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1600 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1601 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1608 * We emit volatile loads for loads which can fault, because otherwise
1609 * LLVM will generate invalid code when encountering a load from a
1612 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1614 /* Mark it with a custom metadata */
1617 set_metadata_flag (res, "mono.faulting.load");
1625 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1627 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1631 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1633 const char *intrins_name;
1634 LLVMValueRef args [16];
1636 if (is_faulting && bb->region != -1) {
1637 LLVMAtomicOrdering ordering;
1640 case LLVM_BARRIER_NONE:
1641 ordering = LLVMAtomicOrderingNotAtomic;
1643 case LLVM_BARRIER_REL:
1644 ordering = LLVMAtomicOrderingRelease;
1646 case LLVM_BARRIER_SEQ:
1647 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1650 g_assert_not_reached ();
1656 intrins_name = "llvm.mono.store.i8.p0i8";
1659 intrins_name = "llvm.mono.store.i16.p0i16";
1662 intrins_name = "llvm.mono.store.i32.p0i32";
1665 intrins_name = "llvm.mono.store.i64.p0i64";
1668 g_assert_not_reached ();
1671 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1672 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1673 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1678 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1679 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1680 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1681 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1683 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1688 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1690 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1694 * emit_cond_system_exception:
1696 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1697 * Might set the ctx exception.
1700 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1702 LLVMBasicBlockRef ex_bb, noex_bb;
1703 LLVMBuilderRef builder;
1704 MonoClass *exc_class;
1705 LLVMValueRef args [2];
1707 ex_bb = gen_bb (ctx, "EX_BB");
1708 noex_bb = gen_bb (ctx, "NOEX_BB");
1710 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1712 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1713 g_assert (exc_class);
1715 /* Emit exception throwing code */
1716 builder = create_builder (ctx);
1717 LLVMPositionBuilderAtEnd (builder, ex_bb);
1719 if (!ctx->lmodule->throw_corlib_exception) {
1720 LLVMValueRef callee;
1722 const char *icall_name;
1724 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1725 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1726 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1727 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1728 /* This will become i8* */
1729 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1730 sig = sig_to_llvm_sig (ctx, throw_sig);
1732 if (ctx->cfg->compile_aot) {
1733 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1735 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1738 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1739 * - On x86, LLVM generated code doesn't push the arguments
1740 * - The trampoline takes the throw address as an arguments, not a pc offset.
1742 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1745 mono_memory_barrier ();
1746 ctx->lmodule->throw_corlib_exception = callee;
1749 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1750 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1752 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1755 * The LLVM mono branch contains changes so a block address can be passed as an
1756 * argument to a call.
1758 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1759 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1761 LLVMBuildUnreachable (builder);
1763 ctx->builder = create_builder (ctx);
1764 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1766 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1773 * emit_args_to_vtype:
1775 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1778 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1780 int j, size, nslots;
1782 size = get_vtype_size (t);
1784 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1785 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1788 if (ainfo->storage == LLVMArgAsFpArgs)
1789 nslots = ainfo->nslots;
1793 for (j = 0; j < nslots; ++j) {
1794 LLVMValueRef index [2], addr, daddr;
1795 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1796 LLVMTypeRef part_type;
1798 if (ainfo->pair_storage [j] == LLVMArgNone)
1801 switch (ainfo->pair_storage [j]) {
1802 case LLVMArgInIReg: {
1803 part_type = LLVMIntType (part_size * 8);
1804 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1805 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1806 addr = LLVMBuildGEP (builder, address, index, 1, "");
1808 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1809 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1810 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1812 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1815 case LLVMArgInFPReg: {
1816 LLVMTypeRef arg_type;
1818 if (ainfo->esize == 8)
1819 arg_type = LLVMDoubleType ();
1821 arg_type = LLVMFloatType ();
1823 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1824 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1825 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1826 LLVMBuildStore (builder, args [j], addr);
1832 g_assert_not_reached ();
1835 size -= sizeof (gpointer);
1840 * emit_vtype_to_args:
1842 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1843 * into ARGS, and the number of arguments into NARGS.
1846 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1849 int j, size, nslots;
1850 LLVMTypeRef arg_type;
1852 size = get_vtype_size (t);
1854 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1855 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1857 if (ainfo->storage == LLVMArgAsFpArgs)
1858 nslots = ainfo->nslots;
1861 for (j = 0; j < nslots; ++j) {
1862 LLVMValueRef index [2], addr, daddr;
1863 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1865 if (ainfo->pair_storage [j] == LLVMArgNone)
1868 switch (ainfo->pair_storage [j]) {
1870 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1871 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1872 addr = LLVMBuildGEP (builder, address, index, 1, "");
1874 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1875 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1876 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1878 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1880 case LLVMArgInFPReg:
1881 if (ainfo->esize == 8)
1882 arg_type = LLVMDoubleType ();
1884 arg_type = LLVMFloatType ();
1885 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1886 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1887 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1888 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1893 g_assert_not_reached ();
1895 size -= sizeof (gpointer);
1902 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1905 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1906 * get executed every time control reaches them.
1908 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1910 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1911 return ctx->last_alloca;
1915 build_alloca (EmitContext *ctx, MonoType *t)
1917 MonoClass *k = mono_class_from_mono_type (t);
1920 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1923 align = mono_class_min_align (k);
1925 /* Sometimes align is not a power of 2 */
1926 while (mono_is_power_of_two (align) == -1)
1929 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1933 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1936 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1939 lmodule->used = g_ptr_array_sized_new (16);
1940 g_ptr_array_add (lmodule->used, global);
1944 emit_llvm_used (MonoLLVMModule *lmodule)
1946 LLVMModuleRef module = lmodule->module;
1947 LLVMTypeRef used_type;
1948 LLVMValueRef used, *used_elem;
1954 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1955 used = LLVMAddGlobal (module, used_type, "llvm.used");
1956 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1957 for (i = 0; i < lmodule->used->len; ++i)
1958 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1959 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1960 LLVMSetLinkage (used, LLVMAppendingLinkage);
1961 LLVMSetSection (used, "llvm.metadata");
1965 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1967 gboolean need_div_check = FALSE;
1969 #ifdef MONO_ARCH_NEED_DIV_CHECK
1970 need_div_check = TRUE;
1973 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1974 need_div_check = TRUE;
1976 if (!need_div_check)
1979 switch (ins->opcode) {
1992 case OP_IDIV_UN_IMM:
1993 case OP_LDIV_UN_IMM:
1994 case OP_IREM_UN_IMM:
1995 case OP_LREM_UN_IMM: {
1997 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1998 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2000 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2001 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2002 CHECK_FAILURE (ctx);
2003 builder = ctx->builder;
2005 /* b == -1 && a == 0x80000000 */
2007 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2008 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2009 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2011 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2012 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2013 CHECK_FAILURE (ctx);
2014 builder = ctx->builder;
2029 * Emit code to load/convert arguments.
2032 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2035 MonoCompile *cfg = ctx->cfg;
2036 MonoMethodSignature *sig = ctx->sig;
2037 LLVMCallInfo *linfo = ctx->linfo;
2040 ctx->alloca_builder = create_builder (ctx);
2043 * Handle indirect/volatile variables by allocating memory for them
2044 * using 'alloca', and storing their address in a temporary.
2046 for (i = 0; i < cfg->num_varinfo; ++i) {
2047 MonoInst *var = cfg->varinfo [i];
2050 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2051 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2052 CHECK_FAILURE (ctx);
2053 /* Could be already created by an OP_VPHI */
2054 if (!ctx->addresses [var->dreg])
2055 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2056 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2060 for (i = 0; i < sig->param_count; ++i) {
2061 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2062 int reg = cfg->args [i + sig->hasthis]->dreg;
2064 switch (ainfo->storage) {
2065 case LLVMArgVtypeInReg:
2066 case LLVMArgAsFpArgs: {
2067 LLVMValueRef args [8];
2070 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2071 memset (args, 0, sizeof (args));
2072 pindex = ctx->pindexes [i];
2073 if (ainfo->storage == LLVMArgVtypeInReg) {
2074 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2075 if (ainfo->pair_storage [1] != LLVMArgNone)
2076 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2078 g_assert (ainfo->nslots <= 8);
2079 for (j = 0; j < ainfo->nslots; ++j)
2080 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2082 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2084 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2086 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2087 /* Treat these as normal values */
2088 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2092 case LLVMArgVtypeByVal: {
2093 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2095 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2096 /* Treat these as normal values */
2097 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2101 case LLVMArgAsIArgs: {
2102 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2104 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2106 /* The argument is received as an array of ints, store it into the real argument */
2107 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2111 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->params [i])), type_is_unsigned (ctx, sig->params [i]));
2117 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2119 emit_volatile_store (ctx, cfg->args [0]->dreg);
2120 for (i = 0; i < sig->param_count; ++i)
2121 if (!mini_type_is_vtype (cfg, sig->params [i]))
2122 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2124 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2125 LLVMValueRef this_alloc;
2128 * The exception handling code needs the location where the this argument was
2129 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2130 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2131 * location into the LSDA.
2133 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2134 /* This volatile store will keep the alloca alive */
2135 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2137 set_metadata_flag (this_alloc, "mono.this");
2140 if (cfg->rgctx_var) {
2141 LLVMValueRef rgctx_alloc, store;
2144 * We handle the rgctx arg similarly to the this pointer.
2146 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2147 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2148 /* This volatile store will keep the alloca alive */
2149 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2151 set_metadata_flag (rgctx_alloc, "mono.this");
2154 /* Compute nesting between clauses */
2155 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2156 for (i = 0; i < cfg->header->num_clauses; ++i) {
2157 for (j = 0; j < cfg->header->num_clauses; ++j) {
2158 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2159 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2161 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2162 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2167 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2168 * it needs to continue normally, or return back to the exception handling system.
2170 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2174 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2177 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2178 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2179 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2181 if (bb->in_scount == 0) {
2184 sprintf (name, "finally_ind_bb%d", bb->block_num);
2185 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2186 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2188 ctx->bblocks [bb->block_num].finally_ind = val;
2190 /* Create a variable to hold the exception var */
2192 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2196 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2197 * LLVM bblock containing a landing pad causes problems for the
2198 * LLVM optimizer passes.
2200 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2201 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2208 /* Have to export this for AOT */
2210 mono_personality (void)
2213 g_assert_not_reached ();
2217 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2219 MonoCompile *cfg = ctx->cfg;
2220 LLVMModuleRef module = ctx->module;
2221 LLVMValueRef *values = ctx->values;
2222 LLVMValueRef *addresses = ctx->addresses;
2223 MonoCallInst *call = (MonoCallInst*)ins;
2224 MonoMethodSignature *sig = call->signature;
2225 LLVMValueRef callee = NULL, lcall;
2227 LLVMCallInfo *cinfo;
2231 LLVMTypeRef llvm_sig;
2233 gboolean virtual, calli;
2234 LLVMBuilderRef builder = *builder_ref;
2237 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2238 LLVM_FAILURE (ctx, "non-default callconv");
2240 cinfo = call->cinfo;
2241 if (call->rgctx_arg_reg)
2242 cinfo->rgctx_arg = TRUE;
2243 if (call->imt_arg_reg)
2244 cinfo->imt_arg = TRUE;
2246 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2248 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2249 CHECK_FAILURE (ctx);
2251 virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
2252 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
2254 /* FIXME: Avoid creating duplicate methods */
2256 if (ins->flags & MONO_INST_HAS_METHOD) {
2260 if (cfg->compile_aot) {
2261 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2263 LLVM_FAILURE (ctx, "can't encode patch");
2265 callee = LLVMAddFunction (module, "", llvm_sig);
2268 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2270 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2274 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2275 /* LLVM miscompiles async methods */
2276 LLVM_FAILURE (ctx, "#13734");
2279 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2285 memset (&ji, 0, sizeof (ji));
2286 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2287 ji.data.target = info->name;
2289 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2291 if (cfg->compile_aot) {
2292 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2294 LLVM_FAILURE (ctx, "can't encode patch");
2296 callee = LLVMAddFunction (module, "", llvm_sig);
2297 target = (gpointer)mono_icall_get_wrapper (info);
2298 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2301 if (cfg->compile_aot) {
2303 if (cfg->abs_patches) {
2304 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2306 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2308 LLVM_FAILURE (ctx, "can't encode patch");
2312 LLVM_FAILURE (ctx, "aot");
2314 callee = LLVMAddFunction (module, "", llvm_sig);
2316 if (cfg->abs_patches) {
2317 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2320 * FIXME: Some trampolines might have
2321 * their own calling convention on some platforms.
2323 #ifndef TARGET_AMD64
2324 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2325 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2326 LLVM_FAILURE (ctx, "trampoline with own cconv");
2328 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2329 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2333 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2339 int size = sizeof (gpointer);
2342 g_assert (ins->inst_offset % size == 0);
2343 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2345 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2347 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2349 if (ins->flags & MONO_INST_HAS_METHOD) {
2354 * Collect and convert arguments
2356 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2357 len = sizeof (LLVMValueRef) * nargs;
2358 args = alloca (len);
2359 memset (args, 0, len);
2360 l = call->out_ireg_args;
2362 if (call->rgctx_arg_reg) {
2363 g_assert (values [call->rgctx_arg_reg]);
2364 g_assert (sinfo.rgctx_arg_pindex < nargs);
2366 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2367 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2368 * it using a volatile load.
2371 if (!ctx->imt_rgctx_loc)
2372 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2373 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2374 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2376 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2379 if (call->imt_arg_reg) {
2380 g_assert (values [call->imt_arg_reg]);
2381 g_assert (sinfo.imt_arg_pindex < nargs);
2383 if (!ctx->imt_rgctx_loc)
2384 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2385 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2386 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2388 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2393 if (!addresses [call->inst.dreg])
2394 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2395 g_assert (sinfo.vret_arg_pindex < nargs);
2396 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2399 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2402 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2406 pindex = sinfo.this_arg_pindex;
2408 pindex = sinfo.pindexes [i - 1];
2410 pindex = sinfo.pindexes [i];
2413 regpair = (guint32)(gssize)(l->data);
2414 reg = regpair & 0xffffff;
2415 args [pindex] = values [reg];
2416 switch (ainfo->storage) {
2417 case LLVMArgVtypeInReg:
2418 case LLVMArgAsFpArgs: {
2421 g_assert (addresses [reg]);
2422 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2426 // FIXME: Get rid of the VMOVE
2429 case LLVMArgVtypeByVal:
2430 g_assert (addresses [reg]);
2431 args [pindex] = addresses [reg];
2433 case LLVMArgAsIArgs:
2434 g_assert (addresses [reg]);
2435 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2438 g_assert (args [pindex]);
2439 if (i == 0 && sig->hasthis)
2440 args [pindex] = convert (ctx, args [pindex], ThisType ());
2442 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2445 g_assert (pindex <= nargs);
2450 // FIXME: Align call sites
2456 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2459 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2461 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2462 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2464 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2465 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2467 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2469 if (call->rgctx_arg_reg)
2470 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2471 if (call->imt_arg_reg)
2472 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2474 /* Add byval attributes if needed */
2475 for (i = 0; i < sig->param_count; ++i) {
2476 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2478 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2479 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2484 * Convert the result
2487 switch (cinfo->ret.storage) {
2488 case LLVMArgVtypeInReg: {
2489 LLVMValueRef regs [2];
2491 if (!addresses [ins->dreg])
2492 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2494 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2495 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2496 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2497 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2500 case LLVMArgVtypeByVal:
2501 if (!addresses [call->inst.dreg])
2502 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2503 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2505 case LLVMArgFpStruct:
2506 if (!addresses [call->inst.dreg])
2507 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2508 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2511 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2512 /* If the method returns an unsigned value, need to zext it */
2513 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2517 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2518 /* If the method returns an unsigned value, need to zext it */
2519 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2523 if (!addresses [call->inst.dreg])
2524 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2525 g_assert (sinfo.vret_arg_pindex < nargs);
2526 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2529 *builder_ref = ctx->builder;
2531 g_free (sinfo.pindexes);
2539 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2541 MonoCompile *cfg = ctx->cfg;
2542 LLVMValueRef *values = ctx->values;
2543 LLVMModuleRef module = ctx->module;
2544 BBInfo *bblocks = ctx->bblocks;
2546 LLVMValueRef personality;
2547 LLVMValueRef landing_pad;
2548 LLVMBasicBlockRef target_bb;
2550 static gint32 mapping_inited;
2551 static int ti_generator;
2554 LLVMValueRef type_info;
2558 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2560 if (cfg->compile_aot) {
2561 /* Use a dummy personality function */
2562 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2563 g_assert (personality);
2565 personality = LLVMGetNamedFunction (module, "mono_personality");
2566 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2567 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2570 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2572 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2575 * Create the type info
2577 sprintf (ti_name, "type_info_%d", ti_generator);
2580 if (cfg->compile_aot) {
2581 /* decode_eh_frame () in aot-runtime.c will decode this */
2582 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2583 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2586 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2588 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2591 * After the cfg mempool is freed, the type info will point to stale memory,
2592 * but this is not a problem, since we decode it once in exception_cb during
2595 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2596 *(gint32*)ti = clause_index;
2598 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2600 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2604 LLVMTypeRef members [2], ret_type;
2606 members [0] = i8ptr;
2607 members [1] = LLVMInt32Type ();
2608 ret_type = LLVMStructType (members, 2, FALSE);
2610 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2611 LLVMAddClause (landing_pad, type_info);
2613 /* Store the exception into the exvar */
2615 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2619 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2620 * code expects control to be transferred to this landing pad even in the
2621 * presence of nested clauses. The landing pad needs to branch to the landing
2622 * pads belonging to nested clauses based on the selector value returned by
2623 * the landing pad instruction, which is passed to the landing pad in a
2624 * register by the EH code.
2626 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2627 g_assert (target_bb);
2630 * Branch to the correct landing pad
2632 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2633 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2635 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2636 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2637 MonoBasicBlock *handler_bb;
2639 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2640 g_assert (handler_bb);
2642 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2643 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2646 /* Start a new bblock which CALL_HANDLER can branch to */
2647 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2649 ctx->builder = builder = create_builder (ctx);
2650 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2652 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2654 /* Store the exception into the IL level exvar */
2655 if (bb->in_scount == 1) {
2656 g_assert (bb->in_scount == 1);
2657 exvar = bb->in_stack [0];
2659 // FIXME: This is shared with filter clauses ?
2660 g_assert (!values [exvar->dreg]);
2662 g_assert (ctx->ex_var);
2663 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2664 emit_volatile_store (ctx, exvar->dreg);
2670 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2672 MonoCompile *cfg = ctx->cfg;
2673 MonoMethodSignature *sig = ctx->sig;
2674 LLVMValueRef method = ctx->lmethod;
2675 LLVMValueRef *values = ctx->values;
2676 LLVMValueRef *addresses = ctx->addresses;
2677 LLVMCallInfo *linfo = ctx->linfo;
2678 LLVMModuleRef module = ctx->module;
2679 BBInfo *bblocks = ctx->bblocks;
2681 LLVMBasicBlockRef cbb;
2682 LLVMBuilderRef builder, starting_builder;
2683 gboolean has_terminator;
2685 LLVMValueRef lhs, rhs;
2688 cbb = get_bb (ctx, bb);
2689 builder = create_builder (ctx);
2690 ctx->builder = builder;
2691 LLVMPositionBuilderAtEnd (builder, cbb);
2693 if (bb == cfg->bb_entry)
2694 emit_entry_bb (ctx, builder);
2695 CHECK_FAILURE (ctx);
2697 if (bb->flags & BB_EXCEPTION_HANDLER) {
2698 if (!bblocks [bb->block_num].invoke_target) {
2700 * Some tests in exceptions.exe fail.
2702 LLVM_FAILURE (ctx, "handler without invokes");
2705 emit_handler_start (ctx, bb, builder);
2706 CHECK_FAILURE (ctx);
2707 builder = ctx->builder;
2710 has_terminator = FALSE;
2711 starting_builder = builder;
2712 for (ins = bb->code; ins; ins = ins->next) {
2713 const char *spec = LLVM_INS_INFO (ins->opcode);
2715 char dname_buf [128];
2717 emit_dbg_loc (ctx, builder, ins->cil_code);
2720 if (nins > 3000 && builder == starting_builder) {
2721 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2722 LLVM_FAILURE (ctx, "basic block too long");
2726 /* There could be instructions after a terminator, skip them */
2729 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2730 sprintf (dname_buf, "t%d", ins->dreg);
2734 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2735 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2737 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2738 lhs = emit_volatile_load (ctx, ins->sreg1);
2740 /* It is ok for SETRET to have an uninitialized argument */
2741 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2742 LLVM_FAILURE (ctx, "sreg1");
2743 lhs = values [ins->sreg1];
2749 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2750 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2751 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2752 rhs = emit_volatile_load (ctx, ins->sreg2);
2754 if (!values [ins->sreg2])
2755 LLVM_FAILURE (ctx, "sreg2");
2756 rhs = values [ins->sreg2];
2762 //mono_print_ins (ins);
2763 switch (ins->opcode) {
2766 case OP_LIVERANGE_START:
2767 case OP_LIVERANGE_END:
2770 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2773 #if SIZEOF_VOID_P == 4
2774 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2776 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2780 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2784 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2786 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2788 case OP_DUMMY_ICONST:
2789 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2791 case OP_DUMMY_I8CONST:
2792 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2794 case OP_DUMMY_R8CONST:
2795 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2798 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2799 has_terminator = TRUE;
2805 LLVMBasicBlockRef new_bb;
2806 LLVMBuilderRef new_builder;
2808 // The default branch is already handled
2809 // FIXME: Handle it here
2811 /* Start new bblock */
2812 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2813 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2815 lhs = convert (ctx, lhs, LLVMInt32Type ());
2816 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2817 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2818 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2820 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2823 new_builder = create_builder (ctx);
2824 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2825 LLVMBuildUnreachable (new_builder);
2827 has_terminator = TRUE;
2828 g_assert (!ins->next);
2834 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2835 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2836 LLVMValueRef part1, retval;
2839 size = get_vtype_size (sig->ret);
2841 g_assert (addresses [ins->sreg1]);
2843 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2844 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2846 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2848 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2850 LLVMBuildRet (builder, retval);
2854 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2855 LLVMValueRef retval;
2857 g_assert (addresses [ins->sreg1]);
2858 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2859 LLVMBuildRet (builder, retval);
2863 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2864 LLVMBuildRetVoid (builder);
2868 if (linfo->ret.storage == LLVMArgFpStruct) {
2869 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2870 LLVMValueRef retval;
2872 g_assert (addresses [ins->sreg1]);
2873 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2874 LLVMBuildRet (builder, retval);
2878 if (!lhs || ctx->is_dead [ins->sreg1]) {
2880 * The method did not set its return value, probably because it
2881 * ends with a throw.
2884 LLVMBuildRetVoid (builder);
2886 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2888 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2890 has_terminator = TRUE;
2897 case OP_ICOMPARE_IMM:
2898 case OP_LCOMPARE_IMM:
2899 case OP_COMPARE_IMM: {
2903 if (ins->next->opcode == OP_NOP)
2906 if (ins->next->opcode == OP_BR)
2907 /* The comparison result is not needed */
2910 rel = mono_opcode_to_cond (ins->next->opcode);
2912 if (ins->opcode == OP_ICOMPARE_IMM) {
2913 lhs = convert (ctx, lhs, LLVMInt32Type ());
2914 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2916 if (ins->opcode == OP_LCOMPARE_IMM) {
2917 lhs = convert (ctx, lhs, LLVMInt64Type ());
2918 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2920 if (ins->opcode == OP_LCOMPARE) {
2921 lhs = convert (ctx, lhs, LLVMInt64Type ());
2922 rhs = convert (ctx, rhs, LLVMInt64Type ());
2924 if (ins->opcode == OP_ICOMPARE) {
2925 lhs = convert (ctx, lhs, LLVMInt32Type ());
2926 rhs = convert (ctx, rhs, LLVMInt32Type ());
2930 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2931 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2932 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2933 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2936 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2937 if (ins->opcode == OP_FCOMPARE) {
2938 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2939 } else if (ins->opcode == OP_RCOMPARE) {
2940 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2941 } else if (ins->opcode == OP_COMPARE_IMM) {
2942 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2943 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2945 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2946 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2947 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2948 /* The immediate is encoded in two fields */
2949 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2950 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2952 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2955 else if (ins->opcode == OP_COMPARE) {
2956 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2957 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2959 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2961 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2963 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2964 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2966 * If the target bb contains PHI instructions, LLVM requires
2967 * two PHI entries for this bblock, while we only generate one.
2968 * So convert this to an unconditional bblock. (bxc #171).
2970 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2972 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2974 has_terminator = TRUE;
2975 } else if (MONO_IS_SETCC (ins->next)) {
2976 sprintf (dname_buf, "t%d", ins->next->dreg);
2978 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2980 /* Add stores for volatile variables */
2981 emit_volatile_store (ctx, ins->next->dreg);
2982 } else if (MONO_IS_COND_EXC (ins->next)) {
2983 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2984 CHECK_FAILURE (ctx);
2985 builder = ctx->builder;
2987 LLVM_FAILURE (ctx, "next");
3001 rel = mono_opcode_to_cond (ins->opcode);
3003 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3004 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3015 rel = mono_opcode_to_cond (ins->opcode);
3017 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3018 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3026 gboolean empty = TRUE;
3028 /* Check that all input bblocks really branch to us */
3029 for (i = 0; i < bb->in_count; ++i) {
3030 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3031 ins->inst_phi_args [i + 1] = -1;
3037 /* LLVM doesn't like phi instructions with zero operands */
3038 ctx->is_dead [ins->dreg] = TRUE;
3042 /* Created earlier, insert it now */
3043 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3045 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3046 int sreg1 = ins->inst_phi_args [i + 1];
3050 * Count the number of times the incoming bblock branches to us,
3051 * since llvm requires a separate entry for each.
3053 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3054 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3057 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3058 if (switch_ins->inst_many_bb [j] == bb)
3065 /* Remember for later */
3066 for (j = 0; j < count; ++j) {
3067 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3070 node->in_bb = bb->in_bb [i];
3072 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);
3082 values [ins->dreg] = lhs;
3086 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3089 values [ins->dreg] = lhs;
3091 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3093 * This is added by the spilling pass in case of the JIT,
3094 * but we have to do it ourselves.
3096 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3100 case OP_MOVE_F_TO_I4: {
3101 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3104 case OP_MOVE_I4_TO_F: {
3105 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3108 case OP_MOVE_F_TO_I8: {
3109 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3112 case OP_MOVE_I8_TO_F: {
3113 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3146 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3147 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3149 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3150 CHECK_FAILURE (ctx);
3151 builder = ctx->builder;
3153 switch (ins->opcode) {
3156 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3160 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3164 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3168 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3172 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3176 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3180 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3184 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3188 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3192 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3196 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3200 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3204 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3208 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3212 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3215 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3218 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3222 g_assert_not_reached ();
3229 lhs = convert (ctx, lhs, LLVMFloatType ());
3230 rhs = convert (ctx, rhs, LLVMFloatType ());
3231 switch (ins->opcode) {
3233 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3236 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3239 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3242 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3245 g_assert_not_reached ();
3254 case OP_IREM_UN_IMM:
3256 case OP_IDIV_UN_IMM:
3262 case OP_ISHR_UN_IMM:
3271 case OP_LSHR_UN_IMM:
3277 case OP_SHR_UN_IMM: {
3280 if (spec [MONO_INST_SRC1] == 'l') {
3281 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3283 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3286 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3287 CHECK_FAILURE (ctx);
3288 builder = ctx->builder;
3290 #if SIZEOF_VOID_P == 4
3291 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3292 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3295 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3296 lhs = convert (ctx, lhs, IntPtrType ());
3297 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3298 switch (ins->opcode) {
3302 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3306 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3310 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3314 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3316 case OP_IDIV_UN_IMM:
3317 case OP_LDIV_UN_IMM:
3318 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3322 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3324 case OP_IREM_UN_IMM:
3325 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3330 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3334 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3338 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3343 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3348 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3350 case OP_ISHR_UN_IMM:
3351 /* This is used to implement conv.u4, so the lhs could be an i8 */
3352 lhs = convert (ctx, lhs, LLVMInt32Type ());
3353 imm = convert (ctx, imm, LLVMInt32Type ());
3354 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3356 case OP_LSHR_UN_IMM:
3358 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3361 g_assert_not_reached ();
3366 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3369 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3372 lhs = convert (ctx, lhs, LLVMDoubleType ());
3373 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3376 lhs = convert (ctx, lhs, LLVMFloatType ());
3377 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3380 guint32 v = 0xffffffff;
3381 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3385 guint64 v = 0xffffffffffffffffLL;
3386 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3389 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3391 LLVMValueRef v1, v2;
3393 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3394 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3395 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3400 case OP_ICONV_TO_I1:
3401 case OP_ICONV_TO_I2:
3402 case OP_ICONV_TO_I4:
3403 case OP_ICONV_TO_U1:
3404 case OP_ICONV_TO_U2:
3405 case OP_ICONV_TO_U4:
3406 case OP_LCONV_TO_I1:
3407 case OP_LCONV_TO_I2:
3408 case OP_LCONV_TO_U1:
3409 case OP_LCONV_TO_U2:
3410 case OP_LCONV_TO_U4: {
3413 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);
3415 /* Have to do two casts since our vregs have type int */
3416 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3418 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3420 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3423 case OP_ICONV_TO_I8:
3424 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3426 case OP_ICONV_TO_U8:
3427 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3429 case OP_FCONV_TO_I4:
3430 case OP_RCONV_TO_I4:
3431 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3433 case OP_FCONV_TO_I1:
3434 case OP_RCONV_TO_I1:
3435 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3437 case OP_FCONV_TO_U1:
3438 case OP_RCONV_TO_U1:
3439 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3441 case OP_FCONV_TO_I2:
3442 case OP_RCONV_TO_I2:
3443 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3445 case OP_FCONV_TO_U2:
3446 case OP_RCONV_TO_U2:
3447 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3449 case OP_FCONV_TO_I8:
3450 case OP_RCONV_TO_I8:
3451 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3454 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3456 case OP_ICONV_TO_R8:
3457 case OP_LCONV_TO_R8:
3458 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3460 case OP_LCONV_TO_R_UN:
3461 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3463 #if SIZEOF_VOID_P == 4
3466 case OP_LCONV_TO_I4:
3467 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3469 case OP_ICONV_TO_R4:
3470 case OP_LCONV_TO_R4:
3471 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3473 values [ins->dreg] = v;
3475 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3477 case OP_FCONV_TO_R4:
3478 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3480 values [ins->dreg] = v;
3482 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3484 case OP_RCONV_TO_R8:
3485 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3487 case OP_RCONV_TO_R4:
3488 values [ins->dreg] = lhs;
3491 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3494 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3497 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3499 case OP_LOCALLOC_IMM: {
3502 guint32 size = ins->inst_imm;
3503 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3505 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3507 if (ins->flags & MONO_INST_INIT) {
3508 LLVMValueRef args [5];
3511 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3512 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3513 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3514 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3515 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3518 values [ins->dreg] = v;
3522 LLVMValueRef v, size;
3524 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), "");
3526 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3528 if (ins->flags & MONO_INST_INIT) {
3529 LLVMValueRef args [5];
3532 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3534 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3535 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3536 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3538 values [ins->dreg] = v;
3542 case OP_LOADI1_MEMBASE:
3543 case OP_LOADU1_MEMBASE:
3544 case OP_LOADI2_MEMBASE:
3545 case OP_LOADU2_MEMBASE:
3546 case OP_LOADI4_MEMBASE:
3547 case OP_LOADU4_MEMBASE:
3548 case OP_LOADI8_MEMBASE:
3549 case OP_LOADR4_MEMBASE:
3550 case OP_LOADR8_MEMBASE:
3551 case OP_LOAD_MEMBASE:
3559 LLVMValueRef base, index, addr;
3561 gboolean sext = FALSE, zext = FALSE;
3562 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3564 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3569 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)) {
3570 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3575 if (ins->inst_offset == 0) {
3577 } else if (ins->inst_offset % size != 0) {
3578 /* Unaligned load */
3579 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3580 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3582 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3583 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3587 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3589 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3591 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3593 * These will signal LLVM that these loads do not alias any stores, and
3594 * they can't fail, allowing them to be hoisted out of loops.
3596 set_invariant_load_flag (values [ins->dreg]);
3597 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3601 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3603 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3604 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3605 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3609 case OP_STOREI1_MEMBASE_REG:
3610 case OP_STOREI2_MEMBASE_REG:
3611 case OP_STOREI4_MEMBASE_REG:
3612 case OP_STOREI8_MEMBASE_REG:
3613 case OP_STORER4_MEMBASE_REG:
3614 case OP_STORER8_MEMBASE_REG:
3615 case OP_STORE_MEMBASE_REG: {
3617 LLVMValueRef index, addr;
3619 gboolean sext = FALSE, zext = FALSE;
3620 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3622 if (!values [ins->inst_destbasereg])
3623 LLVM_FAILURE (ctx, "inst_destbasereg");
3625 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3627 if (ins->inst_offset % size != 0) {
3628 /* Unaligned store */
3629 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3630 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3632 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3633 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3635 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3639 case OP_STOREI1_MEMBASE_IMM:
3640 case OP_STOREI2_MEMBASE_IMM:
3641 case OP_STOREI4_MEMBASE_IMM:
3642 case OP_STOREI8_MEMBASE_IMM:
3643 case OP_STORE_MEMBASE_IMM: {
3645 LLVMValueRef index, addr;
3647 gboolean sext = FALSE, zext = FALSE;
3648 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3650 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3652 if (ins->inst_offset % size != 0) {
3653 /* Unaligned store */
3654 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3655 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3657 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3658 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3660 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3665 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3667 case OP_OUTARG_VTRETADDR:
3675 case OP_VOIDCALL_MEMBASE:
3676 case OP_CALL_MEMBASE:
3677 case OP_LCALL_MEMBASE:
3678 case OP_FCALL_MEMBASE:
3679 case OP_RCALL_MEMBASE:
3680 case OP_VCALL_MEMBASE:
3681 case OP_VOIDCALL_REG:
3686 case OP_VCALL_REG: {
3687 process_call (ctx, bb, &builder, ins);
3688 CHECK_FAILURE (ctx);
3693 LLVMValueRef indexes [2];
3695 LLVMValueRef got_entry_addr;
3698 * FIXME: Can't allocate from the cfg mempool since that is freed if
3699 * the LLVM compile fails.
3701 ji = g_new0 (MonoJumpInfo, 1);
3702 ji->type = (MonoJumpInfoType)ins->inst_i1;
3703 ji->data.target = ins->inst_p0;
3705 ji = mono_aot_patch_info_dup (ji);
3707 ji->next = cfg->patch_info;
3708 cfg->patch_info = ji;
3710 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3711 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3712 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3714 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3715 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3716 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3718 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3719 set_invariant_load_flag (values [ins->dreg]);
3722 case OP_NOT_REACHED:
3723 LLVMBuildUnreachable (builder);
3724 has_terminator = TRUE;
3725 g_assert (bb->block_num < cfg->max_block_num);
3726 ctx->unreachable [bb->block_num] = TRUE;
3727 /* Might have instructions after this */
3729 MonoInst *next = ins->next;
3731 * FIXME: If later code uses the regs defined by these instructions,
3732 * compilation will fail.
3734 MONO_DELETE_INS (bb, next);
3738 MonoInst *var = ins->inst_p0;
3740 values [ins->dreg] = addresses [var->dreg];
3744 LLVMValueRef args [1];
3746 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3747 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3751 LLVMValueRef args [1];
3753 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3754 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3758 LLVMValueRef args [1];
3761 /* This no longer seems to happen */
3763 * LLVM optimizes sqrt(nan) into undefined in
3764 * lib/Analysis/ConstantFolding.cpp
3765 * Also, sqrt(NegativeInfinity) is optimized into 0.
3767 LLVM_FAILURE (ctx, "sqrt");
3769 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3770 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3774 LLVMValueRef args [1];
3776 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3777 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3791 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3792 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3794 switch (ins->opcode) {
3797 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3801 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3805 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3809 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3812 g_assert_not_reached ();
3815 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3818 case OP_ATOMIC_EXCHANGE_I4:
3819 case OP_ATOMIC_EXCHANGE_I8: {
3820 LLVMValueRef args [2];
3823 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3824 t = LLVMInt32Type ();
3826 t = LLVMInt64Type ();
3828 g_assert (ins->inst_offset == 0);
3830 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3831 args [1] = convert (ctx, rhs, t);
3833 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3836 case OP_ATOMIC_ADD_I4:
3837 case OP_ATOMIC_ADD_I8: {
3838 LLVMValueRef args [2];
3841 if (ins->opcode == OP_ATOMIC_ADD_I4)
3842 t = LLVMInt32Type ();
3844 t = LLVMInt64Type ();
3846 g_assert (ins->inst_offset == 0);
3848 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3849 args [1] = convert (ctx, rhs, t);
3850 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3853 case OP_ATOMIC_CAS_I4:
3854 case OP_ATOMIC_CAS_I8: {
3855 LLVMValueRef args [3], val;
3858 if (ins->opcode == OP_ATOMIC_CAS_I4)
3859 t = LLVMInt32Type ();
3861 t = LLVMInt64Type ();
3863 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3865 args [1] = convert (ctx, values [ins->sreg3], t);
3867 args [2] = convert (ctx, values [ins->sreg2], t);
3868 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3869 /* cmpxchg returns a pair */
3870 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3873 case OP_MEMORY_BARRIER: {
3874 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3877 case OP_ATOMIC_LOAD_I1:
3878 case OP_ATOMIC_LOAD_I2:
3879 case OP_ATOMIC_LOAD_I4:
3880 case OP_ATOMIC_LOAD_I8:
3881 case OP_ATOMIC_LOAD_U1:
3882 case OP_ATOMIC_LOAD_U2:
3883 case OP_ATOMIC_LOAD_U4:
3884 case OP_ATOMIC_LOAD_U8:
3885 case OP_ATOMIC_LOAD_R4:
3886 case OP_ATOMIC_LOAD_R8: {
3887 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3890 gboolean sext, zext;
3892 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3893 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3894 LLVMValueRef index, addr;
3896 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3901 if (ins->inst_offset != 0) {
3902 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3903 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3908 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3910 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3913 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3915 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3918 case OP_ATOMIC_STORE_I1:
3919 case OP_ATOMIC_STORE_I2:
3920 case OP_ATOMIC_STORE_I4:
3921 case OP_ATOMIC_STORE_I8:
3922 case OP_ATOMIC_STORE_U1:
3923 case OP_ATOMIC_STORE_U2:
3924 case OP_ATOMIC_STORE_U4:
3925 case OP_ATOMIC_STORE_U8:
3926 case OP_ATOMIC_STORE_R4:
3927 case OP_ATOMIC_STORE_R8: {
3928 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3931 gboolean sext, zext;
3933 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3934 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3935 LLVMValueRef index, addr, value;
3937 if (!values [ins->inst_destbasereg])
3938 LLVM_FAILURE (ctx, "inst_destbasereg");
3940 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3942 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3943 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3944 value = convert (ctx, values [ins->sreg1], t);
3946 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3949 case OP_RELAXED_NOP: {
3950 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3951 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3958 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3960 // 257 == FS segment register
3961 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3963 // 256 == GS segment register
3964 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3967 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3968 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3969 /* See mono_amd64_emit_tls_get () */
3970 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3972 // 256 == GS segment register
3973 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3974 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3976 LLVM_FAILURE (ctx, "opcode tls-get");
3981 case OP_TLS_GET_REG: {
3982 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3983 /* See emit_tls_get_reg () */
3984 // 256 == GS segment register
3985 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3986 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3988 LLVM_FAILURE (ctx, "opcode tls-get");
3997 case OP_IADD_OVF_UN:
3999 case OP_ISUB_OVF_UN:
4001 case OP_IMUL_OVF_UN:
4002 #if SIZEOF_VOID_P == 8
4004 case OP_LADD_OVF_UN:
4006 case OP_LSUB_OVF_UN:
4008 case OP_LMUL_OVF_UN:
4011 LLVMValueRef args [2], val, ovf, func;
4013 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4014 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4015 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4017 val = LLVMBuildCall (builder, func, args, 2, "");
4018 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4019 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4020 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4021 CHECK_FAILURE (ctx);
4022 builder = ctx->builder;
4028 * We currently model them using arrays. Promotion to local vregs is
4029 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4030 * so we always have an entry in cfg->varinfo for them.
4031 * FIXME: Is this needed ?
4034 MonoClass *klass = ins->klass;
4035 LLVMValueRef args [5];
4039 LLVM_FAILURE (ctx, "!klass");
4043 if (!addresses [ins->dreg])
4044 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4045 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4046 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4047 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4049 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4050 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4051 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4054 case OP_DUMMY_VZERO:
4057 case OP_STOREV_MEMBASE:
4058 case OP_LOADV_MEMBASE:
4060 MonoClass *klass = ins->klass;
4061 LLVMValueRef src = NULL, dst, args [5];
4062 gboolean done = FALSE;
4066 LLVM_FAILURE (ctx, "!klass");
4070 if (mini_is_gsharedvt_klass (cfg, klass)) {
4072 LLVM_FAILURE (ctx, "gsharedvt");
4076 switch (ins->opcode) {
4077 case OP_STOREV_MEMBASE:
4078 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4079 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4080 /* Decomposed earlier */
4081 g_assert_not_reached ();
4084 if (!addresses [ins->sreg1]) {
4086 g_assert (values [ins->sreg1]);
4087 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));
4088 LLVMBuildStore (builder, values [ins->sreg1], dst);
4091 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4092 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4095 case OP_LOADV_MEMBASE:
4096 if (!addresses [ins->dreg])
4097 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4098 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4099 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4102 if (!addresses [ins->sreg1])
4103 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4104 if (!addresses [ins->dreg])
4105 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4106 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4107 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4110 g_assert_not_reached ();
4112 CHECK_FAILURE (ctx);
4119 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4120 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4122 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4123 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4124 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4127 case OP_LLVM_OUTARG_VT:
4128 if (!addresses [ins->sreg1]) {
4129 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4130 g_assert (values [ins->sreg1]);
4131 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4133 addresses [ins->dreg] = addresses [ins->sreg1];
4139 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4141 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4144 case OP_LOADX_MEMBASE: {
4145 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4148 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4149 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4152 case OP_STOREX_MEMBASE: {
4153 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4156 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4157 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4164 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4168 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4174 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4178 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4182 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4186 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4189 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4192 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4195 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4199 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4210 LLVMValueRef v = NULL;
4212 switch (ins->opcode) {
4217 t = LLVMVectorType (LLVMInt32Type (), 4);
4218 rt = LLVMVectorType (LLVMFloatType (), 4);
4224 t = LLVMVectorType (LLVMInt64Type (), 2);
4225 rt = LLVMVectorType (LLVMDoubleType (), 2);
4228 t = LLVMInt32Type ();
4229 rt = LLVMInt32Type ();
4230 g_assert_not_reached ();
4233 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4234 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4235 switch (ins->opcode) {
4238 v = LLVMBuildAnd (builder, lhs, rhs, "");
4242 v = LLVMBuildOr (builder, lhs, rhs, "");
4246 v = LLVMBuildXor (builder, lhs, rhs, "");
4250 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4253 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4277 case OP_PADDB_SAT_UN:
4278 case OP_PADDW_SAT_UN:
4279 case OP_PSUBB_SAT_UN:
4280 case OP_PSUBW_SAT_UN:
4288 case OP_PMULW_HIGH_UN: {
4289 LLVMValueRef args [2];
4294 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4301 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4305 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4313 case OP_EXTRACTX_U2:
4315 case OP_EXTRACT_U1: {
4317 gboolean zext = FALSE;
4319 t = simd_op_to_llvm_type (ins->opcode);
4321 switch (ins->opcode) {
4329 case OP_EXTRACTX_U2:
4334 t = LLVMInt32Type ();
4335 g_assert_not_reached ();
4338 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4339 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4341 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4350 case OP_EXPAND_R8: {
4351 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4352 LLVMValueRef mask [16], v;
4355 for (i = 0; i < 16; ++i)
4356 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4358 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4360 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4361 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4366 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4369 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4372 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4375 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4378 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4381 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4392 case OP_EXTRACT_MASK:
4399 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4401 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4407 LLVMValueRef args [3];
4411 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4413 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4418 /* This is only used for implementing shifts by non-immediate */
4419 values [ins->dreg] = lhs;
4430 LLVMValueRef args [3];
4433 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4435 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4446 case OP_PSHLQ_REG: {
4447 LLVMValueRef args [3];
4450 args [1] = values [ins->sreg2];
4452 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4459 case OP_PSHUFLEW_LOW:
4460 case OP_PSHUFLEW_HIGH: {
4462 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4463 int i, mask_size = 0;
4464 int imask = ins->inst_c0;
4466 /* Convert the x86 shuffle mask to LLVM's */
4467 switch (ins->opcode) {
4470 mask [0] = ((imask >> 0) & 3);
4471 mask [1] = ((imask >> 2) & 3);
4472 mask [2] = ((imask >> 4) & 3) + 4;
4473 mask [3] = ((imask >> 6) & 3) + 4;
4474 v1 = values [ins->sreg1];
4475 v2 = values [ins->sreg2];
4479 mask [0] = ((imask >> 0) & 1);
4480 mask [1] = ((imask >> 1) & 1) + 2;
4481 v1 = values [ins->sreg1];
4482 v2 = values [ins->sreg2];
4484 case OP_PSHUFLEW_LOW:
4486 mask [0] = ((imask >> 0) & 3);
4487 mask [1] = ((imask >> 2) & 3);
4488 mask [2] = ((imask >> 4) & 3);
4489 mask [3] = ((imask >> 6) & 3);
4494 v1 = values [ins->sreg1];
4495 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4497 case OP_PSHUFLEW_HIGH:
4503 mask [4] = 4 + ((imask >> 0) & 3);
4504 mask [5] = 4 + ((imask >> 2) & 3);
4505 mask [6] = 4 + ((imask >> 4) & 3);
4506 mask [7] = 4 + ((imask >> 6) & 3);
4507 v1 = values [ins->sreg1];
4508 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4512 mask [0] = ((imask >> 0) & 3);
4513 mask [1] = ((imask >> 2) & 3);
4514 mask [2] = ((imask >> 4) & 3);
4515 mask [3] = ((imask >> 6) & 3);
4516 v1 = values [ins->sreg1];
4517 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4520 g_assert_not_reached ();
4522 for (i = 0; i < mask_size; ++i)
4523 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4525 values [ins->dreg] =
4526 LLVMBuildShuffleVector (builder, v1, v2,
4527 LLVMConstVector (mask_values, mask_size), dname);
4531 case OP_UNPACK_LOWB:
4532 case OP_UNPACK_LOWW:
4533 case OP_UNPACK_LOWD:
4534 case OP_UNPACK_LOWQ:
4535 case OP_UNPACK_LOWPS:
4536 case OP_UNPACK_LOWPD:
4537 case OP_UNPACK_HIGHB:
4538 case OP_UNPACK_HIGHW:
4539 case OP_UNPACK_HIGHD:
4540 case OP_UNPACK_HIGHQ:
4541 case OP_UNPACK_HIGHPS:
4542 case OP_UNPACK_HIGHPD: {
4544 LLVMValueRef mask_values [16];
4545 int i, mask_size = 0;
4546 gboolean low = FALSE;
4548 switch (ins->opcode) {
4549 case OP_UNPACK_LOWB:
4553 case OP_UNPACK_LOWW:
4557 case OP_UNPACK_LOWD:
4558 case OP_UNPACK_LOWPS:
4562 case OP_UNPACK_LOWQ:
4563 case OP_UNPACK_LOWPD:
4567 case OP_UNPACK_HIGHB:
4570 case OP_UNPACK_HIGHW:
4573 case OP_UNPACK_HIGHD:
4574 case OP_UNPACK_HIGHPS:
4577 case OP_UNPACK_HIGHQ:
4578 case OP_UNPACK_HIGHPD:
4582 g_assert_not_reached ();
4586 for (i = 0; i < (mask_size / 2); ++i) {
4588 mask [(i * 2) + 1] = mask_size + i;
4591 for (i = 0; i < (mask_size / 2); ++i) {
4592 mask [(i * 2)] = (mask_size / 2) + i;
4593 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4597 for (i = 0; i < mask_size; ++i)
4598 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4600 values [ins->dreg] =
4601 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4602 LLVMConstVector (mask_values, mask_size), dname);
4607 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4608 LLVMValueRef v, val;
4610 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4611 val = LLVMConstNull (t);
4612 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4613 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4615 values [ins->dreg] = val;
4619 case OP_DUPPS_HIGH: {
4620 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4621 LLVMValueRef v1, v2, val;
4624 if (ins->opcode == OP_DUPPS_LOW) {
4625 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4626 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4628 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4629 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4631 val = LLVMConstNull (t);
4632 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4633 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4634 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4635 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4637 values [ins->dreg] = val;
4647 * EXCEPTION HANDLING
4649 case OP_IMPLICIT_EXCEPTION:
4650 /* This marks a place where an implicit exception can happen */
4651 if (bb->region != -1)
4652 LLVM_FAILURE (ctx, "implicit-exception");
4656 MonoMethodSignature *throw_sig;
4657 LLVMValueRef callee, arg;
4658 gboolean rethrow = (ins->opcode == OP_RETHROW);
4659 const char *icall_name;
4661 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4662 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4665 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4666 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4667 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4668 if (cfg->compile_aot) {
4669 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4671 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4675 * LLVM doesn't push the exception argument, so we need a different
4678 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4680 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4684 mono_memory_barrier ();
4686 ctx->lmodule->rethrow = callee;
4688 ctx->lmodule->throw = callee;
4690 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4691 emit_call (ctx, bb, &builder, callee, &arg, 1);
4694 case OP_CALL_HANDLER: {
4696 * We don't 'call' handlers, but instead simply branch to them.
4697 * The code generated by ENDFINALLY will branch back to us.
4699 LLVMBasicBlockRef noex_bb;
4701 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4703 bb_list = info->call_handler_return_bbs;
4706 * Set the indicator variable for the finally clause.
4708 lhs = info->finally_ind;
4710 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4712 /* Branch to the finally clause */
4713 LLVMBuildBr (builder, info->call_handler_target_bb);
4715 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4716 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4718 builder = ctx->builder = create_builder (ctx);
4719 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4721 bblocks [bb->block_num].end_bblock = noex_bb;
4724 case OP_START_HANDLER: {
4727 case OP_ENDFINALLY: {
4728 LLVMBasicBlockRef resume_bb;
4729 MonoBasicBlock *handler_bb;
4730 LLVMValueRef val, switch_ins, callee;
4734 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4735 g_assert (handler_bb);
4736 info = &bblocks [handler_bb->block_num];
4737 lhs = info->finally_ind;
4740 bb_list = info->call_handler_return_bbs;
4742 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4744 /* Load the finally variable */
4745 val = LLVMBuildLoad (builder, lhs, "");
4747 /* Reset the variable */
4748 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4750 /* Branch to either resume_bb, or to the bblocks in bb_list */
4751 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4753 * The other targets are added at the end to handle OP_CALL_HANDLER
4754 * opcodes processed later.
4756 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4758 builder = ctx->builder = create_builder (ctx);
4759 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4761 if (ctx->cfg->compile_aot) {
4762 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4764 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4766 LLVMBuildCall (builder, callee, NULL, 0, "");
4768 LLVMBuildUnreachable (builder);
4769 has_terminator = TRUE;
4775 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4776 LLVM_FAILURE (ctx, reason);
4781 /* Convert the value to the type required by phi nodes */
4782 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4783 if (!values [ins->dreg])
4785 values [ins->dreg] = addresses [ins->dreg];
4787 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4790 /* Add stores for volatile variables */
4791 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4792 emit_volatile_store (ctx, ins->dreg);
4795 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4796 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4798 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4799 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4800 LLVMBuildRetVoid (builder);
4803 if (bb == cfg->bb_entry)
4804 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4813 * mono_llvm_check_method_supported:
4815 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4816 * compiling a method twice.
4819 mono_llvm_check_method_supported (MonoCompile *cfg)
4823 if (cfg->method->save_lmf) {
4824 cfg->exception_message = g_strdup ("lmf");
4825 cfg->disable_llvm = TRUE;
4827 if (cfg->disable_llvm)
4831 * Nested clauses where one of the clauses is a finally clause is
4832 * not supported, because LLVM can't figure out the control flow,
4833 * probably because we resume exception handling by calling our
4834 * own function instead of using the 'resume' llvm instruction.
4836 for (i = 0; i < cfg->header->num_clauses; ++i) {
4837 for (j = 0; j < cfg->header->num_clauses; ++j) {
4838 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4839 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4841 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4842 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4843 cfg->exception_message = g_strdup ("nested clauses");
4844 cfg->disable_llvm = TRUE;
4849 if (cfg->disable_llvm)
4853 if (cfg->method->dynamic) {
4854 cfg->exception_message = g_strdup ("dynamic.");
4855 cfg->disable_llvm = TRUE;
4857 if (cfg->disable_llvm)
4862 * mono_llvm_emit_method:
4864 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4867 mono_llvm_emit_method (MonoCompile *cfg)
4870 MonoMethodSignature *sig;
4872 LLVMTypeRef method_type;
4873 LLVMValueRef method = NULL;
4875 LLVMValueRef *values;
4876 int i, max_block_num, bb_index;
4877 gboolean last = FALSE;
4878 GPtrArray *phi_values;
4879 LLVMCallInfo *linfo;
4881 LLVMModuleRef module;
4883 GPtrArray *bblock_list;
4884 MonoMethodHeader *header;
4885 MonoExceptionClause *clause;
4889 /* The code below might acquire the loader lock, so use it for global locking */
4890 mono_loader_lock ();
4892 /* Used to communicate with the callbacks */
4893 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4895 ctx = g_new0 (EmitContext, 1);
4897 ctx->mempool = cfg->mempool;
4900 * This maps vregs to the LLVM instruction defining them
4902 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4904 * This maps vregs for volatile variables to the LLVM instruction defining their
4907 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4908 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4909 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4910 phi_values = g_ptr_array_sized_new (256);
4912 * This signals whenever the vreg was defined by a phi node with no input vars
4913 * (i.e. all its input bblocks end with NOT_REACHABLE).
4915 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4916 /* Whenever the bblock is unreachable */
4917 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4919 bblock_list = g_ptr_array_sized_new (256);
4921 ctx->values = values;
4922 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4923 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4925 if (cfg->compile_aot) {
4926 ctx->lmodule = &aot_module;
4927 method_name = mono_aot_get_method_name (cfg);
4928 cfg->llvm_method_name = g_strdup (method_name);
4930 init_jit_module (cfg->domain);
4931 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4932 method_name = mono_method_full_name (cfg->method, TRUE);
4935 module = ctx->module = ctx->lmodule->module;
4938 LLVM_FAILURE (ctx, "gsharedvt");
4942 static int count = 0;
4945 if (g_getenv ("LLVM_COUNT")) {
4946 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4947 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4951 if (count > atoi (g_getenv ("LLVM_COUNT")))
4952 LLVM_FAILURE (ctx, "");
4957 sig = mono_method_signature (cfg->method);
4960 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4962 CHECK_FAILURE (ctx);
4965 linfo->rgctx_arg = TRUE;
4966 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4967 CHECK_FAILURE (ctx);
4970 * This maps parameter indexes in the original signature to the indexes in
4971 * the LLVM signature.
4973 ctx->pindexes = sinfo.pindexes;
4975 method = LLVMAddFunction (module, method_name, method_type);
4976 ctx->lmethod = method;
4978 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4979 LLVMSetLinkage (method, LLVMPrivateLinkage);
4981 LLVMAddFunctionAttr (method, LLVMUWTable);
4983 if (cfg->compile_aot) {
4984 LLVMSetLinkage (method, LLVMInternalLinkage);
4985 if (ctx->lmodule->external_symbols) {
4986 LLVMSetLinkage (method, LLVMExternalLinkage);
4987 LLVMSetVisibility (method, LLVMHiddenVisibility);
4990 LLVMSetLinkage (method, LLVMPrivateLinkage);
4993 if (cfg->method->save_lmf)
4994 LLVM_FAILURE (ctx, "lmf");
4996 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4997 LLVM_FAILURE (ctx, "pinvoke signature");
4999 header = cfg->header;
5000 for (i = 0; i < header->num_clauses; ++i) {
5001 clause = &header->clauses [i];
5002 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5003 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5005 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5006 /* We can't handle inlined methods with clauses */
5007 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5009 if (linfo->rgctx_arg) {
5010 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5012 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5013 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5014 * CC_X86_64_Mono in X86CallingConv.td.
5016 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5017 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5019 if (cfg->vret_addr) {
5020 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5021 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5024 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5025 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5028 names = g_new (char *, sig->param_count);
5029 mono_method_get_param_names (cfg->method, (const char **) names);
5031 for (i = 0; i < sig->param_count; ++i) {
5034 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5035 if (names [i] && names [i][0] != '\0')
5036 name = g_strdup_printf ("arg_%s", names [i]);
5038 name = g_strdup_printf ("arg_%d", i);
5039 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5041 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5042 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5046 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5047 ctx->minfo = mono_debug_lookup_method (cfg->method);
5048 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5052 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5053 max_block_num = MAX (max_block_num, bb->block_num);
5054 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5056 /* Add branches between non-consecutive bblocks */
5057 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5058 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5059 bb->next_bb != bb->last_ins->inst_false_bb) {
5061 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5062 inst->opcode = OP_BR;
5063 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5064 mono_bblock_add_inst (bb, inst);
5069 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5070 * was later optimized away, so clear these flags, and add them back for the still
5071 * present OP_LDADDR instructions.
5073 for (i = 0; i < cfg->next_vreg; ++i) {
5076 ins = get_vreg_to_inst (cfg, i);
5077 if (ins && ins != cfg->rgctx_var)
5078 ins->flags &= ~MONO_INST_INDIRECT;
5082 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5084 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5086 LLVMBuilderRef builder;
5088 char dname_buf[128];
5090 builder = create_builder (ctx);
5092 for (ins = bb->code; ins; ins = ins->next) {
5093 switch (ins->opcode) {
5098 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5100 CHECK_FAILURE (ctx);
5102 if (ins->opcode == OP_VPHI) {
5103 /* Treat valuetype PHI nodes as operating on the address itself */
5104 g_assert (ins->klass);
5105 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5109 * Have to precreate these, as they can be referenced by
5110 * earlier instructions.
5112 sprintf (dname_buf, "t%d", ins->dreg);
5114 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5116 if (ins->opcode == OP_VPHI)
5117 ctx->addresses [ins->dreg] = values [ins->dreg];
5119 g_ptr_array_add (phi_values, values [ins->dreg]);
5122 * Set the expected type of the incoming arguments since these have
5123 * to have the same type.
5125 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5126 int sreg1 = ins->inst_phi_args [i + 1];
5129 ctx->vreg_types [sreg1] = phi_type;
5134 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5143 * Create an ordering for bblocks, use the depth first order first, then
5144 * put the exception handling bblocks last.
5146 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5147 bb = cfg->bblocks [bb_index];
5148 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5149 g_ptr_array_add (bblock_list, bb);
5150 bblocks [bb->block_num].added = TRUE;
5154 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5155 if (!bblocks [bb->block_num].added)
5156 g_ptr_array_add (bblock_list, bb);
5160 * Second pass: generate code.
5162 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5163 bb = g_ptr_array_index (bblock_list, bb_index);
5165 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5168 process_bb (ctx, bb);
5169 CHECK_FAILURE (ctx);
5172 /* Add incoming phi values */
5173 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5174 GSList *l, *ins_list;
5176 ins_list = bblocks [bb->block_num].phi_nodes;
5178 for (l = ins_list; l; l = l->next) {
5179 PhiNode *node = l->data;
5180 MonoInst *phi = node->phi;
5181 int sreg1 = node->sreg;
5182 LLVMBasicBlockRef in_bb;
5187 in_bb = get_end_bb (ctx, node->in_bb);
5189 if (ctx->unreachable [node->in_bb->block_num])
5192 if (!values [sreg1])
5193 /* Can happen with values in EH clauses */
5194 LLVM_FAILURE (ctx, "incoming phi sreg1");
5196 if (phi->opcode == OP_VPHI) {
5197 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5198 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5200 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5202 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5203 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5204 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5209 /* Create the SWITCH statements for ENDFINALLY instructions */
5210 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5211 BBInfo *info = &bblocks [bb->block_num];
5213 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5214 LLVMValueRef switch_ins = l->data;
5215 GSList *bb_list = info->call_handler_return_bbs;
5217 for (i = 0; i < g_slist_length (bb_list); ++i)
5218 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5222 if (cfg->verbose_level > 1)
5223 mono_llvm_dump_value (method);
5225 if (cfg->compile_aot)
5226 mark_as_used (ctx->lmodule, method);
5228 if (cfg->compile_aot) {
5229 LLVMValueRef md_args [16];
5230 LLVMValueRef md_node;
5233 method_index = mono_aot_get_method_index (cfg->orig_method);
5234 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5235 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5236 md_node = LLVMMDNode (md_args, 2);
5237 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5238 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5241 if (cfg->compile_aot) {
5242 /* Don't generate native code, keep the LLVM IR */
5243 if (cfg->compile_aot && cfg->verbose_level)
5244 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5246 //LLVMVerifyFunction(method, 0);
5248 //LLVMVerifyFunction(method, 0);
5249 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5251 if (cfg->verbose_level > 1)
5252 mono_llvm_dump_value (method);
5254 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5256 /* Set by emit_cb */
5257 g_assert (cfg->code_len);
5259 /* FIXME: Free the LLVM IL for the function */
5262 if (ctx->lmodule->method_to_lmethod)
5263 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5270 /* Need to add unused phi nodes as they can be referenced by other values */
5271 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5272 LLVMBuilderRef builder;
5274 builder = create_builder (ctx);
5275 LLVMPositionBuilderAtEnd (builder, phi_bb);
5277 for (i = 0; i < phi_values->len; ++i) {
5278 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5279 if (LLVMGetInstructionParent (v) == NULL)
5280 LLVMInsertIntoBuilder (builder, v);
5283 LLVMDeleteFunction (method);
5288 g_free (ctx->addresses);
5289 g_free (ctx->vreg_types);
5290 g_free (ctx->vreg_cli_types);
5291 g_free (ctx->pindexes);
5292 g_free (ctx->is_dead);
5293 g_free (ctx->unreachable);
5294 g_ptr_array_free (phi_values, TRUE);
5295 g_free (ctx->bblocks);
5296 g_hash_table_destroy (ctx->region_to_handler);
5297 g_hash_table_destroy (ctx->clause_to_handler);
5298 g_free (method_name);
5299 g_ptr_array_free (bblock_list, TRUE);
5301 for (l = ctx->builders; l; l = l->next) {
5302 LLVMBuilderRef builder = l->data;
5303 LLVMDisposeBuilder (builder);
5308 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5310 mono_loader_unlock ();
5314 * mono_llvm_emit_call:
5316 * Same as mono_arch_emit_call () for LLVM.
5319 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5322 MonoMethodSignature *sig;
5323 int i, n, stack_size;
5328 sig = call->signature;
5329 n = sig->param_count + sig->hasthis;
5331 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5333 if (cfg->disable_llvm)
5336 if (sig->call_convention == MONO_CALL_VARARG) {
5337 cfg->exception_message = g_strdup ("varargs");
5338 cfg->disable_llvm = TRUE;
5341 for (i = 0; i < n; ++i) {
5344 ainfo = call->cinfo->args + i;
5346 in = call->args [i];
5348 /* Simply remember the arguments */
5349 switch (ainfo->storage) {
5351 case LLVMArgInFPReg: {
5352 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5355 opcode = mono_type_to_regmove (cfg, t);
5356 if (opcode == OP_FMOVE) {
5357 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5358 ins->dreg = mono_alloc_freg (cfg);
5359 } else if (opcode == OP_LMOVE) {
5360 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5361 ins->dreg = mono_alloc_lreg (cfg);
5363 MONO_INST_NEW (cfg, ins, OP_MOVE);
5364 ins->dreg = mono_alloc_ireg (cfg);
5366 ins->sreg1 = in->dreg;
5369 case LLVMArgVtypeByVal:
5370 case LLVMArgVtypeInReg:
5371 case LLVMArgAsIArgs:
5372 case LLVMArgAsFpArgs:
5373 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5374 ins->dreg = mono_alloc_ireg (cfg);
5375 ins->sreg1 = in->dreg;
5376 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5379 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5380 cfg->exception_message = g_strdup ("ainfo->storage");
5381 cfg->disable_llvm = TRUE;
5385 if (!cfg->disable_llvm) {
5386 MONO_ADD_INS (cfg->cbb, ins);
5387 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5392 static unsigned char*
5393 alloc_cb (LLVMValueRef function, int size)
5397 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5401 return mono_domain_code_reserve (cfg->domain, size);
5403 return mono_domain_code_reserve (mono_domain_get (), size);
5408 emitted_cb (LLVMValueRef function, void *start, void *end)
5412 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5414 cfg->code_len = (guint8*)end - (guint8*)start;
5418 exception_cb (void *data)
5421 MonoJitExceptionInfo *ei;
5422 guint32 ei_len, i, j, nested_len, nindex;
5423 gpointer *type_info;
5424 int this_reg, this_offset;
5426 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5430 * data points to a DWARF FDE structure, convert it to our unwind format and
5432 * An alternative would be to save it directly, and modify our unwinder to work
5435 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);
5436 if (cfg->verbose_level > 1)
5437 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5439 /* Count nested clauses */
5441 for (i = 0; i < ei_len; ++i) {
5442 gint32 cindex1 = *(gint32*)type_info [i];
5443 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5445 for (j = 0; j < cfg->header->num_clauses; ++j) {
5447 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5449 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5455 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5456 cfg->llvm_ex_info_len = ei_len + nested_len;
5457 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5458 /* Fill the rest of the information from the type info */
5459 for (i = 0; i < ei_len; ++i) {
5460 gint32 clause_index = *(gint32*)type_info [i];
5461 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5463 cfg->llvm_ex_info [i].flags = clause->flags;
5464 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5465 cfg->llvm_ex_info [i].clause_index = clause_index;
5469 * For nested clauses, the LLVM produced exception info associates the try interval with
5470 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5471 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5472 * and everything else from the nested clause.
5475 for (i = 0; i < ei_len; ++i) {
5476 gint32 cindex1 = *(gint32*)type_info [i];
5477 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5479 for (j = 0; j < cfg->header->num_clauses; ++j) {
5481 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5482 MonoJitExceptionInfo *nesting_ei, *nested_ei;
5484 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5485 /* clause1 is the nested clause */
5486 nested_ei = &cfg->llvm_ex_info [i];
5487 nesting_ei = &cfg->llvm_ex_info [nindex];
5490 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
5492 nesting_ei->flags = clause2->flags;
5493 nesting_ei->data.catch_class = clause2->data.catch_class;
5494 nesting_ei->clause_index = cindex2;
5498 g_assert (nindex == ei_len + nested_len);
5499 cfg->llvm_this_reg = this_reg;
5500 cfg->llvm_this_offset = this_offset;
5502 /* type_info [i] is cfg mempool allocated, no need to free it */
5509 dlsym_cb (const char *name, void **symbol)
5515 if (!strcmp (name, "__bzero")) {
5516 *symbol = (void*)bzero;
5518 current = mono_dl_open (NULL, 0, NULL);
5521 err = mono_dl_symbol (current, name, symbol);
5523 mono_dl_close (current);
5525 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5526 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5532 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5534 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5538 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5540 LLVMTypeRef param_types [4];
5542 param_types [0] = param_type1;
5543 param_types [1] = param_type2;
5545 AddFunc (module, name, ret_type, param_types, 2);
5549 add_intrinsics (LLVMModuleRef module)
5551 /* Emit declarations of instrinsics */
5553 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5554 * type doesn't seem to do any locking.
5557 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5559 memset_param_count = 5;
5560 memset_func_name = "llvm.memset.p0i8.i32";
5562 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5566 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5568 memcpy_param_count = 5;
5569 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5571 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5575 LLVMTypeRef params [] = { LLVMDoubleType () };
5577 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5578 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5579 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5581 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5582 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5586 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5587 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5588 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5590 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5591 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5592 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5593 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5594 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5595 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5596 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5600 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5601 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5602 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5604 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5605 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5606 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5607 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5608 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5609 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5614 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5616 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5619 /* SSE intrinsics */
5620 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5622 LLVMTypeRef ret_type, arg_types [16];
5625 ret_type = type_to_simd_type (MONO_TYPE_I4);
5626 arg_types [0] = ret_type;
5627 arg_types [1] = ret_type;
5628 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5629 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5631 ret_type = type_to_simd_type (MONO_TYPE_I2);
5632 arg_types [0] = ret_type;
5633 arg_types [1] = ret_type;
5634 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5639 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5640 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5641 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5642 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5643 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5645 ret_type = type_to_simd_type (MONO_TYPE_I1);
5646 arg_types [0] = ret_type;
5647 arg_types [1] = ret_type;
5648 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5649 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5650 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5651 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5652 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5653 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5654 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5656 ret_type = type_to_simd_type (MONO_TYPE_R8);
5657 arg_types [0] = ret_type;
5658 arg_types [1] = ret_type;
5659 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5660 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5661 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5662 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5663 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5665 ret_type = type_to_simd_type (MONO_TYPE_R4);
5666 arg_types [0] = ret_type;
5667 arg_types [1] = ret_type;
5668 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5669 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5670 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5671 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5672 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5675 ret_type = type_to_simd_type (MONO_TYPE_I1);
5676 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5677 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5678 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5679 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5680 ret_type = type_to_simd_type (MONO_TYPE_I2);
5681 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5682 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5683 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5684 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5687 ret_type = type_to_simd_type (MONO_TYPE_R8);
5688 arg_types [0] = ret_type;
5689 arg_types [1] = ret_type;
5690 arg_types [2] = LLVMInt8Type ();
5691 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5692 ret_type = type_to_simd_type (MONO_TYPE_R4);
5693 arg_types [0] = ret_type;
5694 arg_types [1] = ret_type;
5695 arg_types [2] = LLVMInt8Type ();
5696 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5698 /* Conversion ops */
5699 ret_type = type_to_simd_type (MONO_TYPE_R8);
5700 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5701 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5702 ret_type = type_to_simd_type (MONO_TYPE_R4);
5703 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5704 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", 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_R8);
5707 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5708 ret_type = type_to_simd_type (MONO_TYPE_I4);
5709 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5710 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5711 ret_type = type_to_simd_type (MONO_TYPE_R4);
5712 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5713 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5714 ret_type = type_to_simd_type (MONO_TYPE_R8);
5715 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5716 AddFunc (module, "llvm.x86.sse2.cvtps2pd", 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_R8);
5720 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5721 ret_type = type_to_simd_type (MONO_TYPE_I4);
5722 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5723 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5726 ret_type = type_to_simd_type (MONO_TYPE_R8);
5727 arg_types [0] = ret_type;
5728 AddFunc (module, "llvm.x86.sse2.sqrt.pd", 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.sqrt.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.rsqrt.ps", ret_type, arg_types, 1);
5735 ret_type = type_to_simd_type (MONO_TYPE_R4);
5736 arg_types [0] = ret_type;
5737 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5740 ret_type = type_to_simd_type (MONO_TYPE_I2);
5741 arg_types [0] = ret_type;
5742 arg_types [1] = LLVMInt32Type ();
5743 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5744 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5745 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5746 ret_type = type_to_simd_type (MONO_TYPE_I4);
5747 arg_types [0] = ret_type;
5748 arg_types [1] = LLVMInt32Type ();
5749 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5750 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5751 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5752 ret_type = type_to_simd_type (MONO_TYPE_I8);
5753 arg_types [0] = ret_type;
5754 arg_types [1] = LLVMInt32Type ();
5755 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5756 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5759 ret_type = LLVMInt32Type ();
5760 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5761 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5764 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5767 /* Load/Store intrinsics */
5769 LLVMTypeRef arg_types [5];
5773 for (i = 1; i <= 8; i *= 2) {
5774 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5775 arg_types [1] = LLVMInt32Type ();
5776 arg_types [2] = LLVMInt1Type ();
5777 arg_types [3] = LLVMInt32Type ();
5778 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5779 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5781 arg_types [0] = LLVMIntType (i * 8);
5782 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5783 arg_types [2] = LLVMInt32Type ();
5784 arg_types [3] = LLVMInt1Type ();
5785 arg_types [4] = LLVMInt32Type ();
5786 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5787 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5793 add_types (MonoLLVMModule *lmodule)
5795 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5799 mono_llvm_init (void)
5801 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5805 init_jit_module (MonoDomain *domain)
5807 MonoJitICallInfo *info;
5808 MonoJitDomainInfo *dinfo;
5809 MonoLLVMModule *module;
5812 dinfo = domain_jit_info (domain);
5813 if (dinfo->llvm_module)
5816 mono_loader_lock ();
5818 if (dinfo->llvm_module) {
5819 mono_loader_unlock ();
5823 module = g_new0 (MonoLLVMModule, 1);
5825 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5826 module->module = LLVMModuleCreateWithName (name);
5828 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5830 add_intrinsics (module->module);
5833 module->llvm_types = g_hash_table_new (NULL, NULL);
5835 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5837 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5839 mono_memory_barrier ();
5841 dinfo->llvm_module = module;
5843 mono_loader_unlock ();
5847 mono_llvm_cleanup (void)
5849 if (aot_module.module)
5850 LLVMDisposeModule (aot_module.module);
5852 LLVMContextDispose (LLVMGetGlobalContext ());
5856 mono_llvm_free_domain_info (MonoDomain *domain)
5858 MonoJitDomainInfo *info = domain_jit_info (domain);
5859 MonoLLVMModule *module = info->llvm_module;
5865 if (module->llvm_types)
5866 g_hash_table_destroy (module->llvm_types);
5868 mono_llvm_dispose_ee (module->mono_ee);
5870 if (module->bb_names) {
5871 for (i = 0; i < module->bb_names_len; ++i)
5872 g_free (module->bb_names [i]);
5873 g_free (module->bb_names);
5875 //LLVMDisposeModule (module->module);
5879 info->llvm_module = NULL;
5883 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link)
5885 MonoLLVMModule *lmodule = &aot_module;
5887 /* Delete previous module */
5888 if (lmodule->plt_entries)
5889 g_hash_table_destroy (lmodule->plt_entries);
5890 if (lmodule->module)
5891 LLVMDisposeModule (lmodule->module);
5893 memset (lmodule, 0, sizeof (aot_module));
5895 lmodule->module = LLVMModuleCreateWithName ("aot");
5896 lmodule->assembly = assembly;
5897 lmodule->global_prefix = g_strdup (global_prefix);
5898 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
5899 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
5900 lmodule->external_symbols = TRUE;
5901 lmodule->emit_dwarf = emit_dwarf;
5902 lmodule->static_link = static_link;
5903 /* The first few entries are reserved */
5904 lmodule->max_got_offset = 16;
5906 add_intrinsics (lmodule->module);
5907 add_types (lmodule);
5911 * We couldn't compute the type of the LLVM global representing the got because
5912 * its size is only known after all the methods have been emitted. So create
5913 * a dummy variable, and replace all uses it with the real got variable when
5914 * its size is known in mono_llvm_emit_aot_module ().
5917 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
5919 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
5920 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
5923 /* Add a dummy personality function */
5925 LLVMBasicBlockRef lbb;
5926 LLVMBuilderRef lbuilder;
5927 LLVMValueRef personality;
5929 personality = LLVMAddFunction (lmodule->module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5930 LLVMSetLinkage (personality, LLVMInternalLinkage);
5931 lbb = LLVMAppendBasicBlock (personality, "BB0");
5932 lbuilder = LLVMCreateBuilder ();
5933 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5934 LLVMBuildRetVoid (lbuilder);
5935 mark_as_used (lmodule, personality);
5938 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
5939 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5940 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
5941 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
5945 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
5948 LLVMValueRef res, *vals;
5950 vals = g_new0 (LLVMValueRef, nvalues);
5951 for (i = 0; i < nvalues; ++i)
5952 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
5953 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
5959 * mono_llvm_emit_aot_file_info:
5961 * Emit the MonoAotFileInfo structure.
5962 * Same as emit_aot_file_info () in aot-compiler.c.
5965 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
5967 MonoLLVMModule *lmodule = &aot_module;
5969 /* Save these for later */
5970 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
5971 lmodule->has_jitted_code = has_jitted_code;
5975 * mono_llvm_emit_aot_data:
5977 * Emit the binary data DATA pointed to by symbol SYMBOL.
5980 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
5982 MonoLLVMModule *lmodule = &aot_module;
5986 type = LLVMArrayType (LLVMInt8Type (), data_len);
5987 d = LLVMAddGlobal (lmodule->module, type, symbol);
5988 LLVMSetVisibility (d, LLVMHiddenVisibility);
5989 LLVMSetLinkage (d, LLVMInternalLinkage);
5990 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
5991 mono_llvm_set_is_constant (d);
5994 /* Add a reference to a global defined in JITted code */
5996 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
6001 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
6002 v = LLVMAddGlobal (lmodule->module, type, s);
6008 emit_aot_file_info (MonoLLVMModule *lmodule)
6010 LLVMTypeRef file_info_type;
6011 LLVMTypeRef *eltypes, eltype;
6012 LLVMValueRef info_var;
6013 LLVMValueRef *fields;
6014 int i, nfields, tindex;
6015 MonoAotFileInfo *info;
6017 info = &lmodule->aot_info;
6019 /* Create an LLVM type to represent MonoAotFileInfo */
6021 eltypes = g_new (LLVMTypeRef, nfields);
6023 eltypes [tindex ++] = LLVMInt32Type ();
6024 eltypes [tindex ++] = LLVMInt32Type ();
6026 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
6027 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
6029 for (i = 0; i < 13; ++i)
6030 eltypes [tindex ++] = LLVMInt32Type ();
6032 for (i = 0; i < 4; ++i)
6033 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6034 g_assert (tindex == nfields);
6035 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6036 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6038 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
6039 if (lmodule->static_link) {
6040 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
6041 LLVMSetLinkage (info_var, LLVMInternalLinkage);
6043 fields = g_new (LLVMValueRef, nfields);
6045 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6046 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6050 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6051 * for symbols defined in the .s file emitted by the aot compiler.
6053 eltype = eltypes [tindex];
6054 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
6055 fields [tindex ++] = lmodule->got_var;
6056 /* llc defines this directly */
6057 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
6058 if (TRUE || lmodule->has_jitted_code) {
6059 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
6060 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
6061 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
6063 fields [tindex ++] = LLVMConstNull (eltype);
6064 fields [tindex ++] = LLVMConstNull (eltype);
6065 fields [tindex ++] = LLVMConstNull (eltype);
6067 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
6068 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
6069 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
6070 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
6071 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
6072 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
6073 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
6074 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
6075 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
6076 /* Not needed (mem_end) */
6077 fields [tindex ++] = LLVMConstNull (eltype);
6078 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
6079 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
6080 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
6081 if (info->trampoline_size [0]) {
6082 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
6083 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
6084 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
6085 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
6087 fields [tindex ++] = LLVMConstNull (eltype);
6088 fields [tindex ++] = LLVMConstNull (eltype);
6089 fields [tindex ++] = LLVMConstNull (eltype);
6090 fields [tindex ++] = LLVMConstNull (eltype);
6092 if (lmodule->static_link)
6093 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
6095 fields [tindex ++] = LLVMConstNull (eltype);
6096 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
6097 if (TRUE || lmodule->has_jitted_code) {
6098 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
6099 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
6100 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
6101 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
6102 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
6103 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
6105 fields [tindex ++] = LLVMConstNull (eltype);
6106 fields [tindex ++] = LLVMConstNull (eltype);
6107 fields [tindex ++] = LLVMConstNull (eltype);
6108 fields [tindex ++] = LLVMConstNull (eltype);
6109 fields [tindex ++] = LLVMConstNull (eltype);
6110 fields [tindex ++] = LLVMConstNull (eltype);
6114 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6115 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6116 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6117 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6118 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6119 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6120 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6121 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6122 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6123 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6124 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6125 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6126 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6128 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6129 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6130 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6131 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6132 g_assert (tindex == nfields);
6134 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6136 if (lmodule->static_link) {
6140 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
6141 /* Get rid of characters which cannot occur in symbols */
6143 for (p = s; *p; ++p) {
6144 if (!(isalnum (*p) || *p == '_'))
6147 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
6149 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
6150 LLVMSetLinkage (var, LLVMExternalLinkage);
6155 * Emit the aot module into the LLVM bitcode file FILENAME.
6158 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6160 LLVMTypeRef got_type;
6161 LLVMValueRef real_got;
6162 MonoLLVMModule *module = &aot_module;
6165 * Create the real got variable and replace all uses of the dummy variable with
6168 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6169 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6170 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6171 if (module->external_symbols) {
6172 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6173 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6175 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6177 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6179 mark_as_used (&aot_module, real_got);
6181 /* Delete the dummy got so it doesn't become a global */
6182 LLVMDeleteGlobal (aot_module.got_var);
6183 aot_module.got_var = real_got;
6185 emit_llvm_used (&aot_module);
6186 emit_dbg_info (&aot_module, filename, cu_name);
6187 emit_aot_file_info (&aot_module);
6189 /* Replace PLT entries for directly callable methods with the methods themselves */
6191 GHashTableIter iter;
6193 LLVMValueRef callee;
6195 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6196 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6197 if (mono_aot_is_direct_callable (ji)) {
6198 LLVMValueRef lmethod;
6200 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6201 /* The types might not match because the caller might pass an rgctx */
6202 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6203 mono_llvm_replace_uses_of (callee, lmethod);
6204 mono_aot_mark_unused_llvm_plt_entry (ji);
6214 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6215 g_assert_not_reached ();
6220 LLVMWriteBitcodeToFile (aot_module.module, filename);
6225 md_string (const char *s)
6227 return LLVMMDString (s, strlen (s));
6230 /* Debugging support */
6233 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6235 LLVMModuleRef module = lmodule->module;
6236 LLVMValueRef args [16], cu_args [16], cu, ver;
6238 char *build_info, *s, *dir;
6241 * This can only be enabled when LLVM code is emitted into a separate object
6242 * file, since the AOT compiler also emits dwarf info,
6243 * and the abbrev indexes will not be correct since llvm has added its own
6246 if (!lmodule->emit_dwarf)
6250 * Emit dwarf info in the form of LLVM metadata. There is some
6251 * out-of-date documentation at:
6252 * http://llvm.org/docs/SourceLevelDebugging.html
6253 * but most of this was gathered from the llvm and
6258 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6259 /* CU name/compilation dir */
6260 dir = g_path_get_dirname (filename);
6261 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6262 args [1] = LLVMMDString (dir, strlen (dir));
6263 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6266 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6268 build_info = mono_get_runtime_build_info ();
6269 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6270 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6271 g_free (build_info);
6273 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6275 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6276 /* Runtime version */
6277 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6279 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6280 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6282 if (lmodule->subprogram_mds) {
6286 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6287 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6288 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6289 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6291 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6294 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6295 /* Imported modules */
6296 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6298 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6299 /* DebugEmissionKind = FullDebug */
6300 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6301 cu = LLVMMDNode (cu_args, n_cuargs);
6302 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6304 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6305 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6306 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6307 ver = LLVMMDNode (args, 3);
6308 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6310 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6311 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6312 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6313 ver = LLVMMDNode (args, 3);
6314 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6318 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6320 MonoLLVMModule *module = ctx->lmodule;
6321 MonoDebugMethodInfo *minfo = ctx->minfo;
6322 char *source_file, *dir, *filename;
6323 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6324 MonoSymSeqPoint *sym_seq_points;
6330 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6332 source_file = g_strdup ("<unknown>");
6333 dir = g_path_get_dirname (source_file);
6334 filename = g_path_get_basename (source_file);
6336 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6337 args [0] = md_string (filename);
6338 args [1] = md_string (dir);
6339 ctx_args [1] = LLVMMDNode (args, 2);
6340 ctx_md = LLVMMDNode (ctx_args, 2);
6342 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6343 type_args [1] = NULL;
6344 type_args [2] = NULL;
6345 type_args [3] = LLVMMDString ("", 0);
6346 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6347 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6348 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6349 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6350 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6351 type_args [9] = NULL;
6352 type_args [10] = NULL;
6353 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6354 type_args [12] = NULL;
6355 type_args [13] = NULL;
6356 type_args [14] = NULL;
6357 type_md = LLVMMDNode (type_args, 14);
6359 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6360 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6361 /* Source directory + file pair */
6362 args [0] = md_string (filename);
6363 args [1] = md_string (dir);
6364 md_args [1] = LLVMMDNode (args ,2);
6365 md_args [2] = ctx_md;
6366 md_args [3] = md_string (cfg->method->name);
6367 md_args [4] = md_string (name);
6368 md_args [5] = md_string (name);
6371 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6373 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6375 md_args [7] = type_md;
6377 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6379 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6381 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6382 /* Index into a virtual function */
6383 md_args [11] = NULL;
6384 md_args [12] = NULL;
6386 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6388 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6389 /* Pointer to LLVM function */
6390 md_args [15] = method;
6391 /* Function template parameter */
6392 md_args [16] = NULL;
6393 /* Function declaration descriptor */
6394 md_args [17] = NULL;
6395 /* List of function variables */
6396 md_args [18] = LLVMMDNode (args, 0);
6398 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6399 md = LLVMMDNode (md_args, 20);
6401 if (!module->subprogram_mds)
6402 module->subprogram_mds = g_ptr_array_new ();
6403 g_ptr_array_add (module->subprogram_mds, md);
6407 g_free (source_file);
6408 g_free (sym_seq_points);
6414 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6416 MonoCompile *cfg = ctx->cfg;
6418 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6419 MonoDebugSourceLocation *loc;
6420 LLVMValueRef loc_md, md_args [16];
6423 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6427 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6428 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6429 md_args [nmd_args ++] = ctx->dbg_md;
6430 md_args [nmd_args ++] = NULL;
6431 loc_md = LLVMMDNode (md_args, nmd_args);
6432 LLVMSetCurrentDebugLocation (builder, loc_md);
6433 mono_debug_symfile_free_location (loc);
6440 - Emit LLVM IR from the mono IR using the LLVM C API.
6441 - The original arch specific code remains, so we can fall back to it if we run
6442 into something we can't handle.
6446 A partial list of issues:
6447 - Handling of opcodes which can throw exceptions.
6449 In the mono JIT, these are implemented using code like this:
6456 push throw_pos - method
6457 call <exception trampoline>
6459 The problematic part is push throw_pos - method, which cannot be represented
6460 in the LLVM IR, since it does not support label values.
6461 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6462 be implemented in JIT mode ?
6463 -> a possible but slower implementation would use the normal exception
6464 throwing code but it would need to control the placement of the throw code
6465 (it needs to be exactly after the compare+branch).
6466 -> perhaps add a PC offset intrinsics ?
6468 - efficient implementation of .ovf opcodes.
6470 These are currently implemented as:
6471 <ins which sets the condition codes>
6474 Some overflow opcodes are now supported by LLVM SVN.
6476 - exception handling, unwinding.
6477 - SSA is disabled for methods with exception handlers
6478 - How to obtain unwind info for LLVM compiled methods ?
6479 -> this is now solved by converting the unwind info generated by LLVM
6481 - LLVM uses the c++ exception handling framework, while we use our home grown
6482 code, and couldn't use the c++ one:
6483 - its not supported under VC++, other exotic platforms.
6484 - it might be impossible to support filter clauses with it.
6488 The trampolines need a predictable call sequence, since they need to disasm
6489 the calling code to obtain register numbers / offsets.
6491 LLVM currently generates this code in non-JIT mode:
6492 mov -0x98(%rax),%eax
6494 Here, the vtable pointer is lost.
6495 -> solution: use one vtable trampoline per class.
6497 - passing/receiving the IMT pointer/RGCTX.
6498 -> solution: pass them as normal arguments ?
6502 LLVM does not allow the specification of argument registers etc. This means
6503 that all calls are made according to the platform ABI.
6505 - passing/receiving vtypes.
6507 Vtypes passed/received in registers are handled by the front end by using
6508 a signature with scalar arguments, and loading the parts of the vtype into those
6511 Vtypes passed on the stack are handled using the 'byval' attribute.
6515 Supported though alloca, we need to emit the load/store code.
6519 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6520 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6521 This is made easier because the IR is already in SSA form.
6522 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6523 types are frequently used incorrectly.
6528 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6529 it with the file containing the methods emitted by the JIT and the AOT data
6533 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6534 * - each bblock should end with a branch
6535 * - setting the return value, making cfg->ret non-volatile
6536 * - avoid some transformations in the JIT which make it harder for us to generate
6538 * - use pointer types to help optimizations.