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 MonoAotFileInfo aot_info;
69 const char *jit_got_symbol;
70 const char *eh_frame_symbol;
71 LLVMValueRef code_start, code_end;
72 gboolean has_jitted_code;
76 * Information associated by the backend with mono basic blocks.
79 LLVMBasicBlockRef bblock, end_bblock;
80 LLVMValueRef finally_ind;
81 gboolean added, invoke_target;
83 * If this bblock is the start of a finally clause, this is a list of bblocks it
84 * needs to branch to in ENDFINALLY.
86 GSList *call_handler_return_bbs;
88 * If this bblock is the start of a finally clause, this is the bblock that
89 * CALL_HANDLER needs to branch to.
91 LLVMBasicBlockRef call_handler_target_bb;
92 /* The list of switch statements generated by ENDFINALLY instructions */
93 GSList *endfinally_switch_ins_list;
98 * Structure containing emit state
101 MonoMemPool *mempool;
103 /* Maps method names to the corresponding LLVMValueRef */
104 GHashTable *emitted_method_decls;
107 LLVMValueRef lmethod;
108 MonoLLVMModule *lmodule;
109 LLVMModuleRef module;
111 int sindex, default_index, ex_index;
112 LLVMBuilderRef builder;
113 LLVMValueRef *values, *addresses;
114 MonoType **vreg_cli_types;
116 MonoMethodSignature *sig;
118 GHashTable *region_to_handler;
119 GHashTable *clause_to_handler;
120 LLVMBuilderRef alloca_builder;
121 LLVMValueRef last_alloca;
122 LLVMValueRef rgctx_arg;
123 LLVMTypeRef *vreg_types;
125 gboolean *unreachable;
127 LLVMValueRef imt_rgctx_loc;
128 GHashTable *llvm_types;
130 MonoDebugMethodInfo *minfo;
132 /* For every clause, the clauses it is nested in */
140 MonoBasicBlock *in_bb;
145 * Instruction metadata
146 * This is the same as ins_info, but LREG != IREG.
154 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
155 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
162 /* keep in sync with the enum in mini.h */
165 #include "mini-ops.h"
170 #if SIZEOF_VOID_P == 4
171 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
173 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
176 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
179 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
181 #define TRACE_FAILURE(msg)
185 #define IS_TARGET_X86 1
187 #define IS_TARGET_X86 0
191 #define IS_TARGET_AMD64 1
193 #define IS_TARGET_AMD64 0
196 #define LLVM_FAILURE(ctx, reason) do { \
197 TRACE_FAILURE (reason); \
198 (ctx)->cfg->exception_message = g_strdup (reason); \
199 (ctx)->cfg->disable_llvm = TRUE; \
203 #define CHECK_FAILURE(ctx) do { \
204 if ((ctx)->cfg->disable_llvm) \
208 static LLVMIntPredicate cond_to_llvm_cond [] = {
221 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
234 static MonoNativeTlsKey current_cfg_tls_id;
236 static MonoLLVMModule aot_module;
237 static int memset_param_count, memcpy_param_count;
238 static const char *memset_func_name;
239 static const char *memcpy_func_name;
241 static void init_jit_module (MonoDomain *domain);
243 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
244 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
245 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
250 * The LLVM type with width == sizeof (gpointer)
255 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
261 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
267 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
273 * Return the size of the LLVM representation of the vtype T.
276 get_vtype_size (MonoType *t)
280 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
282 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
289 * simd_class_to_llvm_type:
291 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
294 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
296 if (!strcmp (klass->name, "Vector2d")) {
297 return LLVMVectorType (LLVMDoubleType (), 2);
298 } else if (!strcmp (klass->name, "Vector2l")) {
299 return LLVMVectorType (LLVMInt64Type (), 2);
300 } else if (!strcmp (klass->name, "Vector2ul")) {
301 return LLVMVectorType (LLVMInt64Type (), 2);
302 } else if (!strcmp (klass->name, "Vector4i")) {
303 return LLVMVectorType (LLVMInt32Type (), 4);
304 } else if (!strcmp (klass->name, "Vector4ui")) {
305 return LLVMVectorType (LLVMInt32Type (), 4);
306 } else if (!strcmp (klass->name, "Vector4f")) {
307 return LLVMVectorType (LLVMFloatType (), 4);
308 } else if (!strcmp (klass->name, "Vector8s")) {
309 return LLVMVectorType (LLVMInt16Type (), 8);
310 } else if (!strcmp (klass->name, "Vector8us")) {
311 return LLVMVectorType (LLVMInt16Type (), 8);
312 } else if (!strcmp (klass->name, "Vector16sb")) {
313 return LLVMVectorType (LLVMInt8Type (), 16);
314 } else if (!strcmp (klass->name, "Vector16b")) {
315 return LLVMVectorType (LLVMInt8Type (), 16);
317 printf ("%s\n", klass->name);
323 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
324 static inline G_GNUC_UNUSED LLVMTypeRef
325 type_to_simd_type (int type)
329 return LLVMVectorType (LLVMInt8Type (), 16);
331 return LLVMVectorType (LLVMInt16Type (), 8);
333 return LLVMVectorType (LLVMInt32Type (), 4);
335 return LLVMVectorType (LLVMInt64Type (), 2);
337 return LLVMVectorType (LLVMDoubleType (), 2);
339 return LLVMVectorType (LLVMFloatType (), 4);
341 g_assert_not_reached ();
347 create_llvm_type_for_type (MonoClass *klass)
349 int i, size, nfields, esize;
350 LLVMTypeRef *eltypes;
355 t = &klass->byval_arg;
357 if (mini_type_is_hfa (t, &nfields, &esize)) {
359 * This is needed on arm64 where HFAs are returned in
363 eltypes = g_new (LLVMTypeRef, size);
364 for (i = 0; i < size; ++i)
365 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
367 size = get_vtype_size (t);
369 eltypes = g_new (LLVMTypeRef, size);
370 for (i = 0; i < size; ++i)
371 eltypes [i] = LLVMInt8Type ();
374 name = mono_type_full_name (&klass->byval_arg);
375 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
376 LLVMStructSetBody (ltype, eltypes, size, FALSE);
386 * Return the LLVM type corresponding to T.
389 type_to_llvm_type (EmitContext *ctx, MonoType *t)
392 return LLVMPointerType (LLVMInt8Type (), 0);
394 t = mini_get_underlying_type (ctx->cfg, t);
397 return LLVMVoidType ();
399 return LLVMInt8Type ();
401 return LLVMInt16Type ();
403 return LLVMInt32Type ();
405 return LLVMInt8Type ();
407 return LLVMInt16Type ();
409 return LLVMInt32Type ();
410 case MONO_TYPE_BOOLEAN:
411 return LLVMInt8Type ();
414 return LLVMInt64Type ();
416 return LLVMInt16Type ();
418 return LLVMFloatType ();
420 return LLVMDoubleType ();
423 return IntPtrType ();
424 case MONO_TYPE_OBJECT:
425 case MONO_TYPE_CLASS:
426 case MONO_TYPE_ARRAY:
427 case MONO_TYPE_SZARRAY:
428 case MONO_TYPE_STRING:
430 return ObjRefType ();
433 /* Because of generic sharing */
434 return ObjRefType ();
435 case MONO_TYPE_GENERICINST:
436 if (!mono_type_generic_inst_is_valuetype (t))
437 return ObjRefType ();
439 case MONO_TYPE_VALUETYPE:
440 case MONO_TYPE_TYPEDBYREF: {
444 klass = mono_class_from_mono_type (t);
446 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
447 return simd_class_to_llvm_type (ctx, klass);
450 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
452 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
454 ltype = create_llvm_type_for_type (klass);
455 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
461 printf ("X: %d\n", t->type);
462 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
463 ctx->cfg->disable_llvm = TRUE;
471 * Return whenever T is an unsigned int type.
474 type_is_unsigned (EmitContext *ctx, MonoType *t)
491 * type_to_llvm_arg_type:
493 * Same as type_to_llvm_type, but treat i8/i16 as i32.
496 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
498 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
501 * This works on all abis except arm64/ios which passes multiple
502 * arguments in one stack slot.
505 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
507 * LLVM generates code which only sets the lower bits, while JITted
508 * code expects all the bits to be set.
510 ptype = LLVMInt32Type ();
518 * llvm_type_to_stack_type:
520 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
523 static G_GNUC_UNUSED LLVMTypeRef
524 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
528 if (type == LLVMInt8Type ())
529 return LLVMInt32Type ();
530 else if (type == LLVMInt16Type ())
531 return LLVMInt32Type ();
532 else if (!cfg->r4fp && type == LLVMFloatType ())
533 return LLVMDoubleType ();
539 * regtype_to_llvm_type:
541 * Return the LLVM type corresponding to the regtype C used in instruction
545 regtype_to_llvm_type (char c)
549 return LLVMInt32Type ();
551 return LLVMInt64Type ();
553 return LLVMDoubleType ();
562 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
565 op_to_llvm_type (int opcode)
570 return LLVMInt8Type ();
573 return LLVMInt8Type ();
576 return LLVMInt16Type ();
579 return LLVMInt16Type ();
582 return LLVMInt32Type ();
585 return LLVMInt32Type ();
587 return LLVMInt64Type ();
589 return LLVMFloatType ();
591 return LLVMDoubleType ();
593 return LLVMInt64Type ();
595 return LLVMInt32Type ();
597 return LLVMInt64Type ();
602 return LLVMInt8Type ();
607 return LLVMInt16Type ();
610 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
617 return LLVMInt32Type ();
624 return LLVMInt64Type ();
626 printf ("%s\n", mono_inst_name (opcode));
627 g_assert_not_reached ();
633 * load_store_to_llvm_type:
635 * Return the size/sign/zero extension corresponding to the load/store opcode
639 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
645 case OP_LOADI1_MEMBASE:
646 case OP_STOREI1_MEMBASE_REG:
647 case OP_STOREI1_MEMBASE_IMM:
648 case OP_ATOMIC_LOAD_I1:
649 case OP_ATOMIC_STORE_I1:
652 return LLVMInt8Type ();
653 case OP_LOADU1_MEMBASE:
655 case OP_ATOMIC_LOAD_U1:
656 case OP_ATOMIC_STORE_U1:
659 return LLVMInt8Type ();
660 case OP_LOADI2_MEMBASE:
661 case OP_STOREI2_MEMBASE_REG:
662 case OP_STOREI2_MEMBASE_IMM:
663 case OP_ATOMIC_LOAD_I2:
664 case OP_ATOMIC_STORE_I2:
667 return LLVMInt16Type ();
668 case OP_LOADU2_MEMBASE:
670 case OP_ATOMIC_LOAD_U2:
671 case OP_ATOMIC_STORE_U2:
674 return LLVMInt16Type ();
675 case OP_LOADI4_MEMBASE:
676 case OP_LOADU4_MEMBASE:
679 case OP_STOREI4_MEMBASE_REG:
680 case OP_STOREI4_MEMBASE_IMM:
681 case OP_ATOMIC_LOAD_I4:
682 case OP_ATOMIC_STORE_I4:
683 case OP_ATOMIC_LOAD_U4:
684 case OP_ATOMIC_STORE_U4:
686 return LLVMInt32Type ();
687 case OP_LOADI8_MEMBASE:
689 case OP_STOREI8_MEMBASE_REG:
690 case OP_STOREI8_MEMBASE_IMM:
691 case OP_ATOMIC_LOAD_I8:
692 case OP_ATOMIC_STORE_I8:
693 case OP_ATOMIC_LOAD_U8:
694 case OP_ATOMIC_STORE_U8:
696 return LLVMInt64Type ();
697 case OP_LOADR4_MEMBASE:
698 case OP_STORER4_MEMBASE_REG:
699 case OP_ATOMIC_LOAD_R4:
700 case OP_ATOMIC_STORE_R4:
702 return LLVMFloatType ();
703 case OP_LOADR8_MEMBASE:
704 case OP_STORER8_MEMBASE_REG:
705 case OP_ATOMIC_LOAD_R8:
706 case OP_ATOMIC_STORE_R8:
708 return LLVMDoubleType ();
709 case OP_LOAD_MEMBASE:
711 case OP_STORE_MEMBASE_REG:
712 case OP_STORE_MEMBASE_IMM:
713 *size = sizeof (gpointer);
714 return IntPtrType ();
716 g_assert_not_reached ();
724 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
727 ovf_op_to_intrins (int opcode)
731 return "llvm.sadd.with.overflow.i32";
733 return "llvm.uadd.with.overflow.i32";
735 return "llvm.ssub.with.overflow.i32";
737 return "llvm.usub.with.overflow.i32";
739 return "llvm.smul.with.overflow.i32";
741 return "llvm.umul.with.overflow.i32";
743 return "llvm.sadd.with.overflow.i64";
745 return "llvm.uadd.with.overflow.i64";
747 return "llvm.ssub.with.overflow.i64";
749 return "llvm.usub.with.overflow.i64";
751 return "llvm.smul.with.overflow.i64";
753 return "llvm.umul.with.overflow.i64";
755 g_assert_not_reached ();
761 simd_op_to_intrins (int opcode)
764 #if defined(TARGET_X86) || defined(TARGET_AMD64)
766 return "llvm.x86.sse2.min.pd";
768 return "llvm.x86.sse.min.ps";
770 return "llvm.x86.sse41.pminud";
772 return "llvm.x86.sse41.pminuw";
774 return "llvm.x86.sse2.pminu.b";
776 return "llvm.x86.sse2.pmins.w";
778 return "llvm.x86.sse2.max.pd";
780 return "llvm.x86.sse.max.ps";
782 return "llvm.x86.sse3.hadd.pd";
784 return "llvm.x86.sse3.hadd.ps";
786 return "llvm.x86.sse3.hsub.pd";
788 return "llvm.x86.sse3.hsub.ps";
790 return "llvm.x86.sse41.pmaxud";
792 return "llvm.x86.sse41.pmaxuw";
794 return "llvm.x86.sse2.pmaxu.b";
796 return "llvm.x86.sse3.addsub.ps";
798 return "llvm.x86.sse3.addsub.pd";
799 case OP_EXTRACT_MASK:
800 return "llvm.x86.sse2.pmovmskb.128";
803 return "llvm.x86.sse2.psrli.w";
806 return "llvm.x86.sse2.psrli.d";
809 return "llvm.x86.sse2.psrli.q";
812 return "llvm.x86.sse2.pslli.w";
815 return "llvm.x86.sse2.pslli.d";
818 return "llvm.x86.sse2.pslli.q";
821 return "llvm.x86.sse2.psrai.w";
824 return "llvm.x86.sse2.psrai.d";
826 return "llvm.x86.sse2.padds.b";
828 return "llvm.x86.sse2.padds.w";
830 return "llvm.x86.sse2.psubs.b";
832 return "llvm.x86.sse2.psubs.w";
833 case OP_PADDB_SAT_UN:
834 return "llvm.x86.sse2.paddus.b";
835 case OP_PADDW_SAT_UN:
836 return "llvm.x86.sse2.paddus.w";
837 case OP_PSUBB_SAT_UN:
838 return "llvm.x86.sse2.psubus.b";
839 case OP_PSUBW_SAT_UN:
840 return "llvm.x86.sse2.psubus.w";
842 return "llvm.x86.sse2.pavg.b";
844 return "llvm.x86.sse2.pavg.w";
846 return "llvm.x86.sse.sqrt.ps";
848 return "llvm.x86.sse2.sqrt.pd";
850 return "llvm.x86.sse.rsqrt.ps";
852 return "llvm.x86.sse.rcp.ps";
854 return "llvm.x86.sse2.cvtdq2pd";
856 return "llvm.x86.sse2.cvtdq2ps";
858 return "llvm.x86.sse2.cvtpd2dq";
860 return "llvm.x86.sse2.cvtps2dq";
862 return "llvm.x86.sse2.cvtpd2ps";
864 return "llvm.x86.sse2.cvtps2pd";
866 return "llvm.x86.sse2.cvttpd2dq";
868 return "llvm.x86.sse2.cvttps2dq";
870 return "llvm.x86.sse.cmp.ps";
872 return "llvm.x86.sse2.cmp.pd";
874 return "llvm.x86.sse2.packsswb.128";
876 return "llvm.x86.sse2.packssdw.128";
878 return "llvm.x86.sse2.packuswb.128";
880 return "llvm.x86.sse41.packusdw";
882 return "llvm.x86.sse2.pmulh.w";
883 case OP_PMULW_HIGH_UN:
884 return "llvm.x86.sse2.pmulhu.w";
887 g_assert_not_reached ();
893 simd_op_to_llvm_type (int opcode)
895 #if defined(TARGET_X86) || defined(TARGET_AMD64)
899 return type_to_simd_type (MONO_TYPE_R8);
902 return type_to_simd_type (MONO_TYPE_I8);
905 return type_to_simd_type (MONO_TYPE_I4);
910 return type_to_simd_type (MONO_TYPE_I2);
914 return type_to_simd_type (MONO_TYPE_I1);
916 return type_to_simd_type (MONO_TYPE_R4);
919 return type_to_simd_type (MONO_TYPE_I4);
923 return type_to_simd_type (MONO_TYPE_R8);
927 return type_to_simd_type (MONO_TYPE_R4);
928 case OP_EXTRACT_MASK:
929 return type_to_simd_type (MONO_TYPE_I1);
935 return type_to_simd_type (MONO_TYPE_R4);
938 return type_to_simd_type (MONO_TYPE_R8);
940 g_assert_not_reached ();
951 * Return the LLVM basic block corresponding to BB.
953 static LLVMBasicBlockRef
954 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
956 char bb_name_buf [128];
959 if (ctx->bblocks [bb->block_num].bblock == NULL) {
960 if (bb->flags & BB_EXCEPTION_HANDLER) {
961 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
962 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
963 bb_name = bb_name_buf;
964 } else if (bb->block_num < 256) {
965 if (!ctx->lmodule->bb_names) {
966 ctx->lmodule->bb_names_len = 256;
967 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
969 if (!ctx->lmodule->bb_names [bb->block_num]) {
972 n = g_strdup_printf ("BB%d", bb->block_num);
973 mono_memory_barrier ();
974 ctx->lmodule->bb_names [bb->block_num] = n;
976 bb_name = ctx->lmodule->bb_names [bb->block_num];
978 sprintf (bb_name_buf, "BB%d", bb->block_num);
979 bb_name = bb_name_buf;
982 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
983 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
986 return ctx->bblocks [bb->block_num].bblock;
992 * Return the last LLVM bblock corresponding to BB.
993 * This might not be equal to the bb returned by get_bb () since we need to generate
994 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
996 static LLVMBasicBlockRef
997 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1000 return ctx->bblocks [bb->block_num].end_bblock;
1003 static LLVMBasicBlockRef
1004 gen_bb (EmitContext *ctx, const char *prefix)
1008 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1009 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1015 * Return the target of the patch identified by TYPE and TARGET.
1018 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1022 memset (&ji, 0, sizeof (ji));
1024 ji.data.target = target;
1026 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1032 * Emit code to convert the LLVM value V to DTYPE.
1035 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1037 LLVMTypeRef stype = LLVMTypeOf (v);
1039 if (stype != dtype) {
1040 gboolean ext = FALSE;
1043 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1045 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1047 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1051 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1053 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1054 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1057 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1058 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1059 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1060 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1061 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1062 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1063 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1064 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1066 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1067 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1068 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1069 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1070 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1071 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1073 if (mono_arch_is_soft_float ()) {
1074 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1075 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1076 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1077 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1080 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1081 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1084 LLVMDumpValue (LLVMConstNull (dtype));
1085 g_assert_not_reached ();
1093 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1095 return convert_full (ctx, v, dtype, FALSE);
1099 * emit_volatile_load:
1101 * If vreg is volatile, emit a load from its address.
1104 emit_volatile_load (EmitContext *ctx, int vreg)
1108 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1109 t = ctx->vreg_cli_types [vreg];
1110 if (t && !t->byref) {
1112 * Might have to zero extend since llvm doesn't have
1115 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1116 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1117 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1118 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1119 else if (t->type == MONO_TYPE_U8)
1120 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1127 * emit_volatile_store:
1129 * If VREG is volatile, emit a store from its value to its address.
1132 emit_volatile_store (EmitContext *ctx, int vreg)
1134 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1136 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1137 g_assert (ctx->addresses [vreg]);
1138 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1144 * Maps parameter indexes in the original signature to parameter indexes
1145 * in the LLVM signature.
1148 /* The indexes of various special arguments in the LLVM signature */
1149 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1153 * sig_to_llvm_sig_full:
1155 * Return the LLVM signature corresponding to the mono signature SIG using the
1156 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1159 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1162 LLVMTypeRef ret_type;
1163 LLVMTypeRef *param_types = NULL;
1165 int i, j, pindex, vret_arg_pindex = 0;
1167 gboolean vretaddr = FALSE;
1171 memset (sinfo, 0, sizeof (LLVMSigInfo));
1173 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1174 ret_type = type_to_llvm_type (ctx, rtype);
1175 CHECK_FAILURE (ctx);
1178 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1179 /* LLVM models this by returning an aggregate value */
1180 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1181 LLVMTypeRef members [2];
1183 members [0] = IntPtrType ();
1184 ret_type = LLVMStructType (members, 1, FALSE);
1186 g_assert_not_reached ();
1188 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1189 /* Vtype returned normally by val */
1190 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1191 /* Vtype returned as a fp struct */
1192 LLVMTypeRef members [16];
1194 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1195 for (i = 0; i < cinfo->ret.nslots; ++i)
1196 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1197 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1198 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1199 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1201 ret_type = LLVMVoidType ();
1205 pindexes = g_new0 (int, sig->param_count);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1208 if (cinfo && cinfo->rgctx_arg) {
1210 sinfo->rgctx_arg_pindex = pindex;
1211 param_types [pindex] = ctx->lmodule->ptr_type;
1214 if (cinfo && cinfo->imt_arg) {
1216 sinfo->imt_arg_pindex = pindex;
1217 param_types [pindex] = ctx->lmodule->ptr_type;
1221 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1222 vret_arg_pindex = pindex;
1223 if (cinfo->vret_arg_index == 1) {
1224 /* Add the slots consumed by the first argument */
1225 LLVMArgInfo *ainfo = &cinfo->args [0];
1226 switch (ainfo->storage) {
1227 case LLVMArgVtypeInReg:
1228 for (j = 0; j < 2; ++j) {
1229 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1239 sinfo->vret_arg_pindex = vret_arg_pindex;
1242 if (vretaddr && vret_arg_pindex == pindex)
1243 param_types [pindex ++] = IntPtrType ();
1246 sinfo->this_arg_pindex = pindex;
1247 param_types [pindex ++] = ThisType ();
1249 if (vretaddr && vret_arg_pindex == pindex)
1250 param_types [pindex ++] = IntPtrType ();
1251 for (i = 0; i < sig->param_count; ++i) {
1252 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1254 if (vretaddr && vret_arg_pindex == pindex)
1255 param_types [pindex ++] = IntPtrType ();
1256 pindexes [i] = pindex;
1259 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1263 switch (ainfo->storage) {
1264 case LLVMArgVtypeInReg:
1265 for (j = 0; j < 2; ++j) {
1266 switch (ainfo->pair_storage [j]) {
1268 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1273 g_assert_not_reached ();
1277 case LLVMArgVtypeByVal:
1278 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1279 CHECK_FAILURE (ctx);
1280 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1283 case LLVMArgAsIArgs:
1284 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1287 case LLVMArgAsFpArgs: {
1290 for (j = 0; j < ainfo->nslots; ++j)
1291 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 pindex += ainfo->nslots;
1296 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1300 if (vretaddr && vret_arg_pindex == pindex)
1301 param_types [pindex ++] = IntPtrType ();
1303 CHECK_FAILURE (ctx);
1305 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1306 g_free (param_types);
1309 sinfo->pindexes = pindexes;
1317 g_free (param_types);
1323 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1325 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1329 * LLVMFunctionType1:
1331 * Create an LLVM function type from the arguments.
1333 static G_GNUC_UNUSED LLVMTypeRef
1334 LLVMFunctionType1(LLVMTypeRef ReturnType,
1335 LLVMTypeRef ParamType1,
1338 LLVMTypeRef param_types [1];
1340 param_types [0] = ParamType1;
1342 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1346 * LLVMFunctionType2:
1348 * Create an LLVM function type from the arguments.
1350 static G_GNUC_UNUSED LLVMTypeRef
1351 LLVMFunctionType2(LLVMTypeRef ReturnType,
1352 LLVMTypeRef ParamType1,
1353 LLVMTypeRef ParamType2,
1356 LLVMTypeRef param_types [2];
1358 param_types [0] = ParamType1;
1359 param_types [1] = ParamType2;
1361 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1365 * LLVMFunctionType3:
1367 * Create an LLVM function type from the arguments.
1369 static G_GNUC_UNUSED LLVMTypeRef
1370 LLVMFunctionType3(LLVMTypeRef ReturnType,
1371 LLVMTypeRef ParamType1,
1372 LLVMTypeRef ParamType2,
1373 LLVMTypeRef ParamType3,
1376 LLVMTypeRef param_types [3];
1378 param_types [0] = ParamType1;
1379 param_types [1] = ParamType2;
1380 param_types [2] = ParamType3;
1382 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1388 * Create an LLVM builder and remember it so it can be freed later.
1390 static LLVMBuilderRef
1391 create_builder (EmitContext *ctx)
1393 LLVMBuilderRef builder = LLVMCreateBuilder ();
1395 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1401 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1403 char *callee_name = mono_aot_get_plt_symbol (type, data);
1404 LLVMValueRef callee;
1405 MonoJumpInfo *ji = NULL;
1410 if (ctx->cfg->compile_aot)
1411 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1412 mono_add_patch_info (ctx->cfg, 0, type, data);
1415 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1417 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1419 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1421 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1424 if (ctx->cfg->compile_aot) {
1425 ji = g_new0 (MonoJumpInfo, 1);
1427 ji->data.target = data;
1429 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1436 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1438 MonoMethodHeader *header = cfg->header;
1439 MonoExceptionClause *clause;
1443 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1444 return (bb->region >> 8) - 1;
1447 for (i = 0; i < header->num_clauses; ++i) {
1448 clause = &header->clauses [i];
1450 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1458 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1460 LLVMValueRef md_arg;
1463 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1464 md_arg = LLVMMDString ("mono", 4);
1465 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1469 set_invariant_load_flag (LLVMValueRef v)
1471 LLVMValueRef md_arg;
1473 const char *flag_name;
1475 // FIXME: Cache this
1476 flag_name = "invariant.load";
1477 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1478 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1479 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1485 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1489 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1491 MonoCompile *cfg = ctx->cfg;
1493 LLVMBuilderRef builder = *builder_ref;
1496 clause_index = get_handler_clause (cfg, bb);
1498 if (clause_index != -1) {
1499 MonoMethodHeader *header = cfg->header;
1500 MonoExceptionClause *ec = &header->clauses [clause_index];
1501 MonoBasicBlock *tblock;
1502 LLVMBasicBlockRef ex_bb, noex_bb;
1505 * Have to use an invoke instead of a call, branching to the
1506 * handler bblock of the clause containing this bblock.
1509 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1511 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1514 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1516 ex_bb = get_bb (ctx, tblock);
1518 noex_bb = gen_bb (ctx, "NOEX_BB");
1521 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1523 builder = ctx->builder = create_builder (ctx);
1524 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1526 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1528 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1529 ctx->builder = builder;
1532 *builder_ref = ctx->builder;
1538 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1540 const char *intrins_name;
1541 LLVMValueRef args [16], res;
1542 LLVMTypeRef addr_type;
1544 if (is_faulting && bb->region != -1) {
1545 LLVMAtomicOrdering ordering;
1548 case LLVM_BARRIER_NONE:
1549 ordering = LLVMAtomicOrderingNotAtomic;
1551 case LLVM_BARRIER_ACQ:
1552 ordering = LLVMAtomicOrderingAcquire;
1554 case LLVM_BARRIER_SEQ:
1555 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1558 g_assert_not_reached ();
1563 * We handle loads which can fault by calling a mono specific intrinsic
1564 * using an invoke, so they are handled properly inside try blocks.
1565 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1566 * are marked with IntrReadArgMem.
1570 intrins_name = "llvm.mono.load.i8.p0i8";
1573 intrins_name = "llvm.mono.load.i16.p0i16";
1576 intrins_name = "llvm.mono.load.i32.p0i32";
1579 intrins_name = "llvm.mono.load.i64.p0i64";
1582 g_assert_not_reached ();
1585 addr_type = LLVMTypeOf (addr);
1586 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1587 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1590 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1591 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1592 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1593 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1595 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1596 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1597 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1598 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1605 * We emit volatile loads for loads which can fault, because otherwise
1606 * LLVM will generate invalid code when encountering a load from a
1609 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1611 /* Mark it with a custom metadata */
1614 set_metadata_flag (res, "mono.faulting.load");
1622 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1624 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1628 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1630 const char *intrins_name;
1631 LLVMValueRef args [16];
1633 if (is_faulting && bb->region != -1) {
1634 LLVMAtomicOrdering ordering;
1637 case LLVM_BARRIER_NONE:
1638 ordering = LLVMAtomicOrderingNotAtomic;
1640 case LLVM_BARRIER_REL:
1641 ordering = LLVMAtomicOrderingRelease;
1643 case LLVM_BARRIER_SEQ:
1644 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1647 g_assert_not_reached ();
1653 intrins_name = "llvm.mono.store.i8.p0i8";
1656 intrins_name = "llvm.mono.store.i16.p0i16";
1659 intrins_name = "llvm.mono.store.i32.p0i32";
1662 intrins_name = "llvm.mono.store.i64.p0i64";
1665 g_assert_not_reached ();
1668 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1669 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1670 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1675 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1676 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1677 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1678 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1680 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1685 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1687 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1691 * emit_cond_system_exception:
1693 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1694 * Might set the ctx exception.
1697 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1699 LLVMBasicBlockRef ex_bb, noex_bb;
1700 LLVMBuilderRef builder;
1701 MonoClass *exc_class;
1702 LLVMValueRef args [2];
1704 ex_bb = gen_bb (ctx, "EX_BB");
1705 noex_bb = gen_bb (ctx, "NOEX_BB");
1707 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1709 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1710 g_assert (exc_class);
1712 /* Emit exception throwing code */
1713 builder = create_builder (ctx);
1714 LLVMPositionBuilderAtEnd (builder, ex_bb);
1716 if (!ctx->lmodule->throw_corlib_exception) {
1717 LLVMValueRef callee;
1719 const char *icall_name;
1721 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1722 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1723 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1724 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1725 /* This will become i8* */
1726 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1727 sig = sig_to_llvm_sig (ctx, throw_sig);
1729 if (ctx->cfg->compile_aot) {
1730 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1732 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1735 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1736 * - On x86, LLVM generated code doesn't push the arguments
1737 * - The trampoline takes the throw address as an arguments, not a pc offset.
1739 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1742 mono_memory_barrier ();
1743 ctx->lmodule->throw_corlib_exception = callee;
1746 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1747 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1749 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1752 * The LLVM mono branch contains changes so a block address can be passed as an
1753 * argument to a call.
1755 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1756 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1758 LLVMBuildUnreachable (builder);
1760 ctx->builder = create_builder (ctx);
1761 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1763 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1770 * emit_args_to_vtype:
1772 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1775 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1777 int j, size, nslots;
1779 size = get_vtype_size (t);
1781 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1782 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1785 if (ainfo->storage == LLVMArgAsFpArgs)
1786 nslots = ainfo->nslots;
1790 for (j = 0; j < nslots; ++j) {
1791 LLVMValueRef index [2], addr, daddr;
1792 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1793 LLVMTypeRef part_type;
1795 if (ainfo->pair_storage [j] == LLVMArgNone)
1798 switch (ainfo->pair_storage [j]) {
1799 case LLVMArgInIReg: {
1800 part_type = LLVMIntType (part_size * 8);
1801 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1802 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1803 addr = LLVMBuildGEP (builder, address, index, 1, "");
1805 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1806 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1807 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1809 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1812 case LLVMArgInFPReg: {
1813 LLVMTypeRef arg_type;
1815 if (ainfo->esize == 8)
1816 arg_type = LLVMDoubleType ();
1818 arg_type = LLVMFloatType ();
1820 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1821 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1822 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1823 LLVMBuildStore (builder, args [j], addr);
1829 g_assert_not_reached ();
1832 size -= sizeof (gpointer);
1837 * emit_vtype_to_args:
1839 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1840 * into ARGS, and the number of arguments into NARGS.
1843 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1846 int j, size, nslots;
1847 LLVMTypeRef arg_type;
1849 size = get_vtype_size (t);
1851 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1852 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1854 if (ainfo->storage == LLVMArgAsFpArgs)
1855 nslots = ainfo->nslots;
1858 for (j = 0; j < nslots; ++j) {
1859 LLVMValueRef index [2], addr, daddr;
1860 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1862 if (ainfo->pair_storage [j] == LLVMArgNone)
1865 switch (ainfo->pair_storage [j]) {
1867 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1868 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1869 addr = LLVMBuildGEP (builder, address, index, 1, "");
1871 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1872 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1873 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1875 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1877 case LLVMArgInFPReg:
1878 if (ainfo->esize == 8)
1879 arg_type = LLVMDoubleType ();
1881 arg_type = LLVMFloatType ();
1882 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1883 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1884 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1885 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1890 g_assert_not_reached ();
1892 size -= sizeof (gpointer);
1899 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1902 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1903 * get executed every time control reaches them.
1905 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1907 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1908 return ctx->last_alloca;
1912 build_alloca (EmitContext *ctx, MonoType *t)
1914 MonoClass *k = mono_class_from_mono_type (t);
1917 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1920 align = mono_class_min_align (k);
1922 /* Sometimes align is not a power of 2 */
1923 while (mono_is_power_of_two (align) == -1)
1926 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1930 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1933 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1936 lmodule->used = g_ptr_array_sized_new (16);
1937 g_ptr_array_add (lmodule->used, global);
1941 emit_llvm_used (MonoLLVMModule *lmodule)
1943 LLVMModuleRef module = lmodule->module;
1944 LLVMTypeRef used_type;
1945 LLVMValueRef used, *used_elem;
1951 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1952 used = LLVMAddGlobal (module, used_type, "llvm.used");
1953 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1954 for (i = 0; i < lmodule->used->len; ++i)
1955 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1956 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1957 LLVMSetLinkage (used, LLVMAppendingLinkage);
1958 LLVMSetSection (used, "llvm.metadata");
1962 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1964 gboolean need_div_check = FALSE;
1966 #ifdef MONO_ARCH_NEED_DIV_CHECK
1967 need_div_check = TRUE;
1970 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1971 need_div_check = TRUE;
1973 if (!need_div_check)
1976 switch (ins->opcode) {
1989 case OP_IDIV_UN_IMM:
1990 case OP_LDIV_UN_IMM:
1991 case OP_IREM_UN_IMM:
1992 case OP_LREM_UN_IMM: {
1994 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1995 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
1997 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
1998 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
1999 CHECK_FAILURE (ctx);
2000 builder = ctx->builder;
2002 /* b == -1 && a == 0x80000000 */
2004 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2005 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2006 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2008 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2009 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2010 CHECK_FAILURE (ctx);
2011 builder = ctx->builder;
2026 * Emit code to load/convert arguments.
2029 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2032 MonoCompile *cfg = ctx->cfg;
2033 MonoMethodSignature *sig = ctx->sig;
2034 LLVMCallInfo *linfo = ctx->linfo;
2037 ctx->alloca_builder = create_builder (ctx);
2040 * Handle indirect/volatile variables by allocating memory for them
2041 * using 'alloca', and storing their address in a temporary.
2043 for (i = 0; i < cfg->num_varinfo; ++i) {
2044 MonoInst *var = cfg->varinfo [i];
2047 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2048 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2049 CHECK_FAILURE (ctx);
2050 /* Could be already created by an OP_VPHI */
2051 if (!ctx->addresses [var->dreg])
2052 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2053 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2057 for (i = 0; i < sig->param_count; ++i) {
2058 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2059 int reg = cfg->args [i + sig->hasthis]->dreg;
2061 switch (ainfo->storage) {
2062 case LLVMArgVtypeInReg:
2063 case LLVMArgAsFpArgs: {
2064 LLVMValueRef args [8];
2067 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2068 memset (args, 0, sizeof (args));
2069 pindex = ctx->pindexes [i];
2070 if (ainfo->storage == LLVMArgVtypeInReg) {
2071 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2072 if (ainfo->pair_storage [1] != LLVMArgNone)
2073 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2075 g_assert (ainfo->nslots <= 8);
2076 for (j = 0; j < ainfo->nslots; ++j)
2077 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2079 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2081 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2083 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2084 /* Treat these as normal values */
2085 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2089 case LLVMArgVtypeByVal: {
2090 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2092 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2093 /* Treat these as normal values */
2094 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2098 case LLVMArgAsIArgs: {
2099 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2101 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2103 /* The argument is received as an array of ints, store it into the real argument */
2104 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2108 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]));
2114 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2116 emit_volatile_store (ctx, cfg->args [0]->dreg);
2117 for (i = 0; i < sig->param_count; ++i)
2118 if (!mini_type_is_vtype (cfg, sig->params [i]))
2119 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2121 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2122 LLVMValueRef this_alloc;
2125 * The exception handling code needs the location where the this argument was
2126 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2127 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2128 * location into the LSDA.
2130 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2131 /* This volatile store will keep the alloca alive */
2132 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2134 set_metadata_flag (this_alloc, "mono.this");
2137 if (cfg->rgctx_var) {
2138 LLVMValueRef rgctx_alloc, store;
2141 * We handle the rgctx arg similarly to the this pointer.
2143 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2144 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2145 /* This volatile store will keep the alloca alive */
2146 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2148 set_metadata_flag (rgctx_alloc, "mono.this");
2151 /* Compute nesting between clauses */
2152 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2153 for (i = 0; i < cfg->header->num_clauses; ++i) {
2154 for (j = 0; j < cfg->header->num_clauses; ++j) {
2155 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2156 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2158 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2159 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2164 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2165 * it needs to continue normally, or return back to the exception handling system.
2167 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2171 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2174 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2175 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2176 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2178 if (bb->in_scount == 0) {
2181 sprintf (name, "finally_ind_bb%d", bb->block_num);
2182 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2183 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2185 ctx->bblocks [bb->block_num].finally_ind = val;
2187 /* Create a variable to hold the exception var */
2189 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2193 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2194 * LLVM bblock containing a landing pad causes problems for the
2195 * LLVM optimizer passes.
2197 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2198 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2205 /* Have to export this for AOT */
2207 mono_personality (void)
2210 g_assert_not_reached ();
2214 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2216 MonoCompile *cfg = ctx->cfg;
2217 LLVMModuleRef module = ctx->module;
2218 LLVMValueRef *values = ctx->values;
2219 LLVMValueRef *addresses = ctx->addresses;
2220 MonoCallInst *call = (MonoCallInst*)ins;
2221 MonoMethodSignature *sig = call->signature;
2222 LLVMValueRef callee = NULL, lcall;
2224 LLVMCallInfo *cinfo;
2228 LLVMTypeRef llvm_sig;
2230 gboolean virtual, calli;
2231 LLVMBuilderRef builder = *builder_ref;
2234 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2235 LLVM_FAILURE (ctx, "non-default callconv");
2237 cinfo = call->cinfo;
2238 if (call->rgctx_arg_reg)
2239 cinfo->rgctx_arg = TRUE;
2240 if (call->imt_arg_reg)
2241 cinfo->imt_arg = TRUE;
2243 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2245 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2246 CHECK_FAILURE (ctx);
2248 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);
2249 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);
2251 /* FIXME: Avoid creating duplicate methods */
2253 if (ins->flags & MONO_INST_HAS_METHOD) {
2257 if (cfg->compile_aot) {
2258 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2260 LLVM_FAILURE (ctx, "can't encode patch");
2262 callee = LLVMAddFunction (module, "", llvm_sig);
2265 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2267 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2271 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2272 /* LLVM miscompiles async methods */
2273 LLVM_FAILURE (ctx, "#13734");
2276 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2282 memset (&ji, 0, sizeof (ji));
2283 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2284 ji.data.target = info->name;
2286 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2288 if (cfg->compile_aot) {
2289 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2291 LLVM_FAILURE (ctx, "can't encode patch");
2293 callee = LLVMAddFunction (module, "", llvm_sig);
2294 target = (gpointer)mono_icall_get_wrapper (info);
2295 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2298 if (cfg->compile_aot) {
2300 if (cfg->abs_patches) {
2301 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2303 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2305 LLVM_FAILURE (ctx, "can't encode patch");
2309 LLVM_FAILURE (ctx, "aot");
2311 callee = LLVMAddFunction (module, "", llvm_sig);
2313 if (cfg->abs_patches) {
2314 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2317 * FIXME: Some trampolines might have
2318 * their own calling convention on some platforms.
2320 #ifndef TARGET_AMD64
2321 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2322 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2323 LLVM_FAILURE (ctx, "trampoline with own cconv");
2325 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2326 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2330 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2336 int size = sizeof (gpointer);
2339 g_assert (ins->inst_offset % size == 0);
2340 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2342 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2344 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2346 if (ins->flags & MONO_INST_HAS_METHOD) {
2351 * Collect and convert arguments
2353 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2354 len = sizeof (LLVMValueRef) * nargs;
2355 args = alloca (len);
2356 memset (args, 0, len);
2357 l = call->out_ireg_args;
2359 if (call->rgctx_arg_reg) {
2360 g_assert (values [call->rgctx_arg_reg]);
2361 g_assert (sinfo.rgctx_arg_pindex < nargs);
2363 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2364 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2365 * it using a volatile load.
2368 if (!ctx->imt_rgctx_loc)
2369 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2370 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2371 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2373 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2376 if (call->imt_arg_reg) {
2377 g_assert (values [call->imt_arg_reg]);
2378 g_assert (sinfo.imt_arg_pindex < nargs);
2380 if (!ctx->imt_rgctx_loc)
2381 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2382 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2383 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2385 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2390 if (!addresses [call->inst.dreg])
2391 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2392 g_assert (sinfo.vret_arg_pindex < nargs);
2393 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2396 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2399 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2403 pindex = sinfo.this_arg_pindex;
2405 pindex = sinfo.pindexes [i - 1];
2407 pindex = sinfo.pindexes [i];
2410 regpair = (guint32)(gssize)(l->data);
2411 reg = regpair & 0xffffff;
2412 args [pindex] = values [reg];
2413 switch (ainfo->storage) {
2414 case LLVMArgVtypeInReg:
2415 case LLVMArgAsFpArgs: {
2418 g_assert (addresses [reg]);
2419 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2423 // FIXME: Get rid of the VMOVE
2426 case LLVMArgVtypeByVal:
2427 g_assert (addresses [reg]);
2428 args [pindex] = addresses [reg];
2430 case LLVMArgAsIArgs:
2431 g_assert (addresses [reg]);
2432 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2435 g_assert (args [pindex]);
2436 if (i == 0 && sig->hasthis)
2437 args [pindex] = convert (ctx, args [pindex], ThisType ());
2439 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2442 g_assert (pindex <= nargs);
2447 // FIXME: Align call sites
2453 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2456 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2458 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2459 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2461 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2462 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2464 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2466 if (call->rgctx_arg_reg)
2467 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2468 if (call->imt_arg_reg)
2469 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2471 /* Add byval attributes if needed */
2472 for (i = 0; i < sig->param_count; ++i) {
2473 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2475 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2476 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2481 * Convert the result
2484 switch (cinfo->ret.storage) {
2485 case LLVMArgVtypeInReg: {
2486 LLVMValueRef regs [2];
2488 if (!addresses [ins->dreg])
2489 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2491 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2492 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2493 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2494 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2497 case LLVMArgVtypeByVal:
2498 if (!addresses [call->inst.dreg])
2499 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2500 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2502 case LLVMArgFpStruct:
2503 if (!addresses [call->inst.dreg])
2504 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2505 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2508 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2509 /* If the method returns an unsigned value, need to zext it */
2510 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));
2514 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2515 /* If the method returns an unsigned value, need to zext it */
2516 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));
2520 if (!addresses [call->inst.dreg])
2521 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2522 g_assert (sinfo.vret_arg_pindex < nargs);
2523 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2526 *builder_ref = ctx->builder;
2528 g_free (sinfo.pindexes);
2536 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2538 MonoCompile *cfg = ctx->cfg;
2539 LLVMValueRef *values = ctx->values;
2540 LLVMModuleRef module = ctx->module;
2541 BBInfo *bblocks = ctx->bblocks;
2543 LLVMValueRef personality;
2544 LLVMValueRef landing_pad;
2545 LLVMBasicBlockRef target_bb;
2547 static gint32 mapping_inited;
2548 static int ti_generator;
2551 LLVMValueRef type_info;
2555 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2557 if (cfg->compile_aot) {
2558 /* Use a dummy personality function */
2559 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2560 g_assert (personality);
2562 personality = LLVMGetNamedFunction (module, "mono_personality");
2563 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2564 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2567 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2569 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2572 * Create the type info
2574 sprintf (ti_name, "type_info_%d", ti_generator);
2577 if (cfg->compile_aot) {
2578 /* decode_eh_frame () in aot-runtime.c will decode this */
2579 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2580 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2583 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2585 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2588 * After the cfg mempool is freed, the type info will point to stale memory,
2589 * but this is not a problem, since we decode it once in exception_cb during
2592 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2593 *(gint32*)ti = clause_index;
2595 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2597 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2601 LLVMTypeRef members [2], ret_type;
2603 members [0] = i8ptr;
2604 members [1] = LLVMInt32Type ();
2605 ret_type = LLVMStructType (members, 2, FALSE);
2607 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2608 LLVMAddClause (landing_pad, type_info);
2610 /* Store the exception into the exvar */
2612 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2616 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2617 * code expects control to be transferred to this landing pad even in the
2618 * presence of nested clauses. The landing pad needs to branch to the landing
2619 * pads belonging to nested clauses based on the selector value returned by
2620 * the landing pad instruction, which is passed to the landing pad in a
2621 * register by the EH code.
2623 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2624 g_assert (target_bb);
2627 * Branch to the correct landing pad
2629 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2630 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2632 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2633 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2634 MonoBasicBlock *handler_bb;
2636 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2637 g_assert (handler_bb);
2639 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2640 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2643 /* Start a new bblock which CALL_HANDLER can branch to */
2644 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2646 ctx->builder = builder = create_builder (ctx);
2647 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2649 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2651 /* Store the exception into the IL level exvar */
2652 if (bb->in_scount == 1) {
2653 g_assert (bb->in_scount == 1);
2654 exvar = bb->in_stack [0];
2656 // FIXME: This is shared with filter clauses ?
2657 g_assert (!values [exvar->dreg]);
2659 g_assert (ctx->ex_var);
2660 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2661 emit_volatile_store (ctx, exvar->dreg);
2667 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2669 MonoCompile *cfg = ctx->cfg;
2670 MonoMethodSignature *sig = ctx->sig;
2671 LLVMValueRef method = ctx->lmethod;
2672 LLVMValueRef *values = ctx->values;
2673 LLVMValueRef *addresses = ctx->addresses;
2674 LLVMCallInfo *linfo = ctx->linfo;
2675 LLVMModuleRef module = ctx->module;
2676 BBInfo *bblocks = ctx->bblocks;
2678 LLVMBasicBlockRef cbb;
2679 LLVMBuilderRef builder, starting_builder;
2680 gboolean has_terminator;
2682 LLVMValueRef lhs, rhs;
2685 cbb = get_bb (ctx, bb);
2686 builder = create_builder (ctx);
2687 ctx->builder = builder;
2688 LLVMPositionBuilderAtEnd (builder, cbb);
2690 if (bb == cfg->bb_entry)
2691 emit_entry_bb (ctx, builder);
2692 CHECK_FAILURE (ctx);
2694 if (bb->flags & BB_EXCEPTION_HANDLER) {
2695 if (!bblocks [bb->block_num].invoke_target) {
2697 * LLVM asserts if llvm.eh.selector is called from a bblock which
2698 * doesn't have an invoke pointing at it.
2699 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2701 LLVM_FAILURE (ctx, "handler without invokes");
2704 emit_handler_start (ctx, bb, builder);
2705 CHECK_FAILURE (ctx);
2706 builder = ctx->builder;
2709 has_terminator = FALSE;
2710 starting_builder = builder;
2711 for (ins = bb->code; ins; ins = ins->next) {
2712 const char *spec = LLVM_INS_INFO (ins->opcode);
2714 char dname_buf [128];
2716 emit_dbg_loc (ctx, builder, ins->cil_code);
2719 if (nins > 3000 && builder == starting_builder) {
2720 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2721 LLVM_FAILURE (ctx, "basic block too long");
2725 /* There could be instructions after a terminator, skip them */
2728 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2729 sprintf (dname_buf, "t%d", ins->dreg);
2733 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2734 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2736 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2737 lhs = emit_volatile_load (ctx, ins->sreg1);
2739 /* It is ok for SETRET to have an uninitialized argument */
2740 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2741 LLVM_FAILURE (ctx, "sreg1");
2742 lhs = values [ins->sreg1];
2748 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2749 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2750 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2751 rhs = emit_volatile_load (ctx, ins->sreg2);
2753 if (!values [ins->sreg2])
2754 LLVM_FAILURE (ctx, "sreg2");
2755 rhs = values [ins->sreg2];
2761 //mono_print_ins (ins);
2762 switch (ins->opcode) {
2765 case OP_LIVERANGE_START:
2766 case OP_LIVERANGE_END:
2769 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2772 #if SIZEOF_VOID_P == 4
2773 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2775 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2779 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2783 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2785 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2787 case OP_DUMMY_ICONST:
2788 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2790 case OP_DUMMY_I8CONST:
2791 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2793 case OP_DUMMY_R8CONST:
2794 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2797 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2798 has_terminator = TRUE;
2804 LLVMBasicBlockRef new_bb;
2805 LLVMBuilderRef new_builder;
2807 // The default branch is already handled
2808 // FIXME: Handle it here
2810 /* Start new bblock */
2811 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2812 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2814 lhs = convert (ctx, lhs, LLVMInt32Type ());
2815 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2816 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2817 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2819 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2822 new_builder = create_builder (ctx);
2823 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2824 LLVMBuildUnreachable (new_builder);
2826 has_terminator = TRUE;
2827 g_assert (!ins->next);
2833 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2834 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2835 LLVMValueRef part1, retval;
2838 size = get_vtype_size (sig->ret);
2840 g_assert (addresses [ins->sreg1]);
2842 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2843 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2845 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2847 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2849 LLVMBuildRet (builder, retval);
2853 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2854 LLVMValueRef retval;
2856 g_assert (addresses [ins->sreg1]);
2857 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2858 LLVMBuildRet (builder, retval);
2862 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2863 LLVMBuildRetVoid (builder);
2867 if (linfo->ret.storage == LLVMArgFpStruct) {
2868 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2869 LLVMValueRef retval;
2871 g_assert (addresses [ins->sreg1]);
2872 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2873 LLVMBuildRet (builder, retval);
2877 if (!lhs || ctx->is_dead [ins->sreg1]) {
2879 * The method did not set its return value, probably because it
2880 * ends with a throw.
2883 LLVMBuildRetVoid (builder);
2885 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2887 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2889 has_terminator = TRUE;
2896 case OP_ICOMPARE_IMM:
2897 case OP_LCOMPARE_IMM:
2898 case OP_COMPARE_IMM: {
2902 if (ins->next->opcode == OP_NOP)
2905 if (ins->next->opcode == OP_BR)
2906 /* The comparison result is not needed */
2909 rel = mono_opcode_to_cond (ins->next->opcode);
2911 if (ins->opcode == OP_ICOMPARE_IMM) {
2912 lhs = convert (ctx, lhs, LLVMInt32Type ());
2913 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2915 if (ins->opcode == OP_LCOMPARE_IMM) {
2916 lhs = convert (ctx, lhs, LLVMInt64Type ());
2917 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2919 if (ins->opcode == OP_LCOMPARE) {
2920 lhs = convert (ctx, lhs, LLVMInt64Type ());
2921 rhs = convert (ctx, rhs, LLVMInt64Type ());
2923 if (ins->opcode == OP_ICOMPARE) {
2924 lhs = convert (ctx, lhs, LLVMInt32Type ());
2925 rhs = convert (ctx, rhs, LLVMInt32Type ());
2929 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2930 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2931 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2932 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2935 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2936 if (ins->opcode == OP_FCOMPARE) {
2937 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2938 } else if (ins->opcode == OP_RCOMPARE) {
2939 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2940 } else if (ins->opcode == OP_COMPARE_IMM) {
2941 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2942 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2944 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2945 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2946 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2947 /* The immediate is encoded in two fields */
2948 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2949 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2951 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2954 else if (ins->opcode == OP_COMPARE) {
2955 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2956 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2958 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2960 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2962 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2963 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2965 * If the target bb contains PHI instructions, LLVM requires
2966 * two PHI entries for this bblock, while we only generate one.
2967 * So convert this to an unconditional bblock. (bxc #171).
2969 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2971 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2973 has_terminator = TRUE;
2974 } else if (MONO_IS_SETCC (ins->next)) {
2975 sprintf (dname_buf, "t%d", ins->next->dreg);
2977 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2979 /* Add stores for volatile variables */
2980 emit_volatile_store (ctx, ins->next->dreg);
2981 } else if (MONO_IS_COND_EXC (ins->next)) {
2982 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2983 CHECK_FAILURE (ctx);
2984 builder = ctx->builder;
2986 LLVM_FAILURE (ctx, "next");
3000 rel = mono_opcode_to_cond (ins->opcode);
3002 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3003 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3014 rel = mono_opcode_to_cond (ins->opcode);
3016 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3017 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3025 gboolean empty = TRUE;
3027 /* Check that all input bblocks really branch to us */
3028 for (i = 0; i < bb->in_count; ++i) {
3029 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3030 ins->inst_phi_args [i + 1] = -1;
3036 /* LLVM doesn't like phi instructions with zero operands */
3037 ctx->is_dead [ins->dreg] = TRUE;
3041 /* Created earlier, insert it now */
3042 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3044 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3045 int sreg1 = ins->inst_phi_args [i + 1];
3049 * Count the number of times the incoming bblock branches to us,
3050 * since llvm requires a separate entry for each.
3052 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3053 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3056 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3057 if (switch_ins->inst_many_bb [j] == bb)
3064 /* Remember for later */
3065 for (j = 0; j < count; ++j) {
3066 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3069 node->in_bb = bb->in_bb [i];
3071 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);
3081 values [ins->dreg] = lhs;
3085 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3088 values [ins->dreg] = lhs;
3090 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3092 * This is added by the spilling pass in case of the JIT,
3093 * but we have to do it ourselves.
3095 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3099 case OP_MOVE_F_TO_I4: {
3100 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3103 case OP_MOVE_I4_TO_F: {
3104 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3107 case OP_MOVE_F_TO_I8: {
3108 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3111 case OP_MOVE_I8_TO_F: {
3112 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3145 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3146 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3148 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3149 CHECK_FAILURE (ctx);
3150 builder = ctx->builder;
3152 switch (ins->opcode) {
3155 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3159 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3163 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3167 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3171 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3175 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3179 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3183 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3187 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3191 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3195 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3199 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3203 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3207 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3211 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3214 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3217 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3221 g_assert_not_reached ();
3228 lhs = convert (ctx, lhs, LLVMFloatType ());
3229 rhs = convert (ctx, rhs, LLVMFloatType ());
3230 switch (ins->opcode) {
3232 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3235 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3238 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3241 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3244 g_assert_not_reached ();
3253 case OP_IREM_UN_IMM:
3255 case OP_IDIV_UN_IMM:
3261 case OP_ISHR_UN_IMM:
3270 case OP_LSHR_UN_IMM:
3276 case OP_SHR_UN_IMM: {
3279 if (spec [MONO_INST_SRC1] == 'l') {
3280 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3282 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3285 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3286 CHECK_FAILURE (ctx);
3287 builder = ctx->builder;
3289 #if SIZEOF_VOID_P == 4
3290 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3291 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3294 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3295 lhs = convert (ctx, lhs, IntPtrType ());
3296 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3297 switch (ins->opcode) {
3301 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3305 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3309 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3313 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3315 case OP_IDIV_UN_IMM:
3316 case OP_LDIV_UN_IMM:
3317 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3321 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3323 case OP_IREM_UN_IMM:
3324 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3329 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3333 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3337 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3342 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3347 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3349 case OP_ISHR_UN_IMM:
3350 /* This is used to implement conv.u4, so the lhs could be an i8 */
3351 lhs = convert (ctx, lhs, LLVMInt32Type ());
3352 imm = convert (ctx, imm, LLVMInt32Type ());
3353 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3355 case OP_LSHR_UN_IMM:
3357 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3360 g_assert_not_reached ();
3365 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3368 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3371 lhs = convert (ctx, lhs, LLVMDoubleType ());
3372 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3375 lhs = convert (ctx, lhs, LLVMFloatType ());
3376 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3379 guint32 v = 0xffffffff;
3380 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3384 guint64 v = 0xffffffffffffffffLL;
3385 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3388 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3390 LLVMValueRef v1, v2;
3392 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3393 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3394 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3399 case OP_ICONV_TO_I1:
3400 case OP_ICONV_TO_I2:
3401 case OP_ICONV_TO_I4:
3402 case OP_ICONV_TO_U1:
3403 case OP_ICONV_TO_U2:
3404 case OP_ICONV_TO_U4:
3405 case OP_LCONV_TO_I1:
3406 case OP_LCONV_TO_I2:
3407 case OP_LCONV_TO_U1:
3408 case OP_LCONV_TO_U2:
3409 case OP_LCONV_TO_U4: {
3412 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);
3414 /* Have to do two casts since our vregs have type int */
3415 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3417 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3419 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3422 case OP_ICONV_TO_I8:
3423 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3425 case OP_ICONV_TO_U8:
3426 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3428 case OP_FCONV_TO_I4:
3429 case OP_RCONV_TO_I4:
3430 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3432 case OP_FCONV_TO_I1:
3433 case OP_RCONV_TO_I1:
3434 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3436 case OP_FCONV_TO_U1:
3437 case OP_RCONV_TO_U1:
3438 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3440 case OP_FCONV_TO_I2:
3441 case OP_RCONV_TO_I2:
3442 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3444 case OP_FCONV_TO_U2:
3445 case OP_RCONV_TO_U2:
3446 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3448 case OP_FCONV_TO_I8:
3449 case OP_RCONV_TO_I8:
3450 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3453 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3455 case OP_ICONV_TO_R8:
3456 case OP_LCONV_TO_R8:
3457 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3459 case OP_LCONV_TO_R_UN:
3460 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3462 #if SIZEOF_VOID_P == 4
3465 case OP_LCONV_TO_I4:
3466 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3468 case OP_ICONV_TO_R4:
3469 case OP_LCONV_TO_R4:
3470 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3472 values [ins->dreg] = v;
3474 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3476 case OP_FCONV_TO_R4:
3477 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3479 values [ins->dreg] = v;
3481 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3483 case OP_RCONV_TO_R8:
3484 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3486 case OP_RCONV_TO_R4:
3487 values [ins->dreg] = lhs;
3490 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3493 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3496 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3498 case OP_LOCALLOC_IMM: {
3501 guint32 size = ins->inst_imm;
3502 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3504 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3506 if (ins->flags & MONO_INST_INIT) {
3507 LLVMValueRef args [5];
3510 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3511 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3512 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3513 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3514 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3517 values [ins->dreg] = v;
3521 LLVMValueRef v, size;
3523 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), "");
3525 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3527 if (ins->flags & MONO_INST_INIT) {
3528 LLVMValueRef args [5];
3531 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3533 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3534 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3535 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3537 values [ins->dreg] = v;
3541 case OP_LOADI1_MEMBASE:
3542 case OP_LOADU1_MEMBASE:
3543 case OP_LOADI2_MEMBASE:
3544 case OP_LOADU2_MEMBASE:
3545 case OP_LOADI4_MEMBASE:
3546 case OP_LOADU4_MEMBASE:
3547 case OP_LOADI8_MEMBASE:
3548 case OP_LOADR4_MEMBASE:
3549 case OP_LOADR8_MEMBASE:
3550 case OP_LOAD_MEMBASE:
3558 LLVMValueRef base, index, addr;
3560 gboolean sext = FALSE, zext = FALSE;
3561 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3563 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3568 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)) {
3569 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3574 if (ins->inst_offset == 0) {
3576 } else if (ins->inst_offset % size != 0) {
3577 /* Unaligned load */
3578 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3579 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3581 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3582 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3586 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3588 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3590 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3592 * These will signal LLVM that these loads do not alias any stores, and
3593 * they can't fail, allowing them to be hoisted out of loops.
3595 set_invariant_load_flag (values [ins->dreg]);
3596 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3600 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3602 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3603 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3604 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3608 case OP_STOREI1_MEMBASE_REG:
3609 case OP_STOREI2_MEMBASE_REG:
3610 case OP_STOREI4_MEMBASE_REG:
3611 case OP_STOREI8_MEMBASE_REG:
3612 case OP_STORER4_MEMBASE_REG:
3613 case OP_STORER8_MEMBASE_REG:
3614 case OP_STORE_MEMBASE_REG: {
3616 LLVMValueRef index, addr;
3618 gboolean sext = FALSE, zext = FALSE;
3619 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3621 if (!values [ins->inst_destbasereg])
3622 LLVM_FAILURE (ctx, "inst_destbasereg");
3624 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3626 if (ins->inst_offset % size != 0) {
3627 /* Unaligned store */
3628 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3629 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3631 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3632 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3634 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3638 case OP_STOREI1_MEMBASE_IMM:
3639 case OP_STOREI2_MEMBASE_IMM:
3640 case OP_STOREI4_MEMBASE_IMM:
3641 case OP_STOREI8_MEMBASE_IMM:
3642 case OP_STORE_MEMBASE_IMM: {
3644 LLVMValueRef index, addr;
3646 gboolean sext = FALSE, zext = FALSE;
3647 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3649 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3651 if (ins->inst_offset % size != 0) {
3652 /* Unaligned store */
3653 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3654 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3656 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3657 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3659 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3664 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3666 case OP_OUTARG_VTRETADDR:
3674 case OP_VOIDCALL_MEMBASE:
3675 case OP_CALL_MEMBASE:
3676 case OP_LCALL_MEMBASE:
3677 case OP_FCALL_MEMBASE:
3678 case OP_RCALL_MEMBASE:
3679 case OP_VCALL_MEMBASE:
3680 case OP_VOIDCALL_REG:
3685 case OP_VCALL_REG: {
3686 process_call (ctx, bb, &builder, ins);
3687 CHECK_FAILURE (ctx);
3692 LLVMValueRef indexes [2];
3694 LLVMValueRef got_entry_addr;
3697 * FIXME: Can't allocate from the cfg mempool since that is freed if
3698 * the LLVM compile fails.
3700 ji = g_new0 (MonoJumpInfo, 1);
3701 ji->type = (MonoJumpInfoType)ins->inst_i1;
3702 ji->data.target = ins->inst_p0;
3704 ji = mono_aot_patch_info_dup (ji);
3706 ji->next = cfg->patch_info;
3707 cfg->patch_info = ji;
3709 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3710 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3711 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3713 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3714 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3715 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3717 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3718 set_invariant_load_flag (values [ins->dreg]);
3721 case OP_NOT_REACHED:
3722 LLVMBuildUnreachable (builder);
3723 has_terminator = TRUE;
3724 g_assert (bb->block_num < cfg->max_block_num);
3725 ctx->unreachable [bb->block_num] = TRUE;
3726 /* Might have instructions after this */
3728 MonoInst *next = ins->next;
3730 * FIXME: If later code uses the regs defined by these instructions,
3731 * compilation will fail.
3733 MONO_DELETE_INS (bb, next);
3737 MonoInst *var = ins->inst_p0;
3739 values [ins->dreg] = addresses [var->dreg];
3743 LLVMValueRef args [1];
3745 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3746 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3750 LLVMValueRef args [1];
3752 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3753 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3757 LLVMValueRef args [1];
3760 /* This no longer seems to happen */
3762 * LLVM optimizes sqrt(nan) into undefined in
3763 * lib/Analysis/ConstantFolding.cpp
3764 * Also, sqrt(NegativeInfinity) is optimized into 0.
3766 LLVM_FAILURE (ctx, "sqrt");
3768 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3769 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3773 LLVMValueRef args [1];
3775 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3776 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3790 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3791 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3793 switch (ins->opcode) {
3796 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3800 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3804 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3808 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3811 g_assert_not_reached ();
3814 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3817 case OP_ATOMIC_EXCHANGE_I4:
3818 case OP_ATOMIC_EXCHANGE_I8: {
3819 LLVMValueRef args [2];
3822 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3823 t = LLVMInt32Type ();
3825 t = LLVMInt64Type ();
3827 g_assert (ins->inst_offset == 0);
3829 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3830 args [1] = convert (ctx, rhs, t);
3832 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3835 case OP_ATOMIC_ADD_I4:
3836 case OP_ATOMIC_ADD_I8: {
3837 LLVMValueRef args [2];
3840 if (ins->opcode == OP_ATOMIC_ADD_I4)
3841 t = LLVMInt32Type ();
3843 t = LLVMInt64Type ();
3845 g_assert (ins->inst_offset == 0);
3847 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3848 args [1] = convert (ctx, rhs, t);
3849 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3852 case OP_ATOMIC_CAS_I4:
3853 case OP_ATOMIC_CAS_I8: {
3854 LLVMValueRef args [3], val;
3857 if (ins->opcode == OP_ATOMIC_CAS_I4)
3858 t = LLVMInt32Type ();
3860 t = LLVMInt64Type ();
3862 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3864 args [1] = convert (ctx, values [ins->sreg3], t);
3866 args [2] = convert (ctx, values [ins->sreg2], t);
3867 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3868 /* cmpxchg returns a pair */
3869 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3872 case OP_MEMORY_BARRIER: {
3873 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3876 case OP_ATOMIC_LOAD_I1:
3877 case OP_ATOMIC_LOAD_I2:
3878 case OP_ATOMIC_LOAD_I4:
3879 case OP_ATOMIC_LOAD_I8:
3880 case OP_ATOMIC_LOAD_U1:
3881 case OP_ATOMIC_LOAD_U2:
3882 case OP_ATOMIC_LOAD_U4:
3883 case OP_ATOMIC_LOAD_U8:
3884 case OP_ATOMIC_LOAD_R4:
3885 case OP_ATOMIC_LOAD_R8: {
3886 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3889 gboolean sext, zext;
3891 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3892 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3893 LLVMValueRef index, addr;
3895 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3900 if (ins->inst_offset != 0) {
3901 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3902 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3907 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3909 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3912 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3914 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3917 case OP_ATOMIC_STORE_I1:
3918 case OP_ATOMIC_STORE_I2:
3919 case OP_ATOMIC_STORE_I4:
3920 case OP_ATOMIC_STORE_I8:
3921 case OP_ATOMIC_STORE_U1:
3922 case OP_ATOMIC_STORE_U2:
3923 case OP_ATOMIC_STORE_U4:
3924 case OP_ATOMIC_STORE_U8:
3925 case OP_ATOMIC_STORE_R4:
3926 case OP_ATOMIC_STORE_R8: {
3927 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3930 gboolean sext, zext;
3932 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3933 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3934 LLVMValueRef index, addr, value;
3936 if (!values [ins->inst_destbasereg])
3937 LLVM_FAILURE (ctx, "inst_destbasereg");
3939 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3941 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3942 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3943 value = convert (ctx, values [ins->sreg1], t);
3945 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3948 case OP_RELAXED_NOP: {
3949 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3950 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3957 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3959 // 257 == FS segment register
3960 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3962 // 256 == GS segment register
3963 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3966 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3967 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3968 /* See mono_amd64_emit_tls_get () */
3969 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3971 // 256 == GS segment register
3972 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3973 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3975 LLVM_FAILURE (ctx, "opcode tls-get");
3980 case OP_TLS_GET_REG: {
3981 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3982 /* See emit_tls_get_reg () */
3983 // 256 == GS segment register
3984 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3985 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3987 LLVM_FAILURE (ctx, "opcode tls-get");
3996 case OP_IADD_OVF_UN:
3998 case OP_ISUB_OVF_UN:
4000 case OP_IMUL_OVF_UN:
4001 #if SIZEOF_VOID_P == 8
4003 case OP_LADD_OVF_UN:
4005 case OP_LSUB_OVF_UN:
4007 case OP_LMUL_OVF_UN:
4010 LLVMValueRef args [2], val, ovf, func;
4012 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4013 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4014 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4016 val = LLVMBuildCall (builder, func, args, 2, "");
4017 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4018 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4019 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4020 CHECK_FAILURE (ctx);
4021 builder = ctx->builder;
4027 * We currently model them using arrays. Promotion to local vregs is
4028 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4029 * so we always have an entry in cfg->varinfo for them.
4030 * FIXME: Is this needed ?
4033 MonoClass *klass = ins->klass;
4034 LLVMValueRef args [5];
4038 LLVM_FAILURE (ctx, "!klass");
4042 if (!addresses [ins->dreg])
4043 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4044 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4045 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4046 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4048 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4049 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4050 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4053 case OP_DUMMY_VZERO:
4056 case OP_STOREV_MEMBASE:
4057 case OP_LOADV_MEMBASE:
4059 MonoClass *klass = ins->klass;
4060 LLVMValueRef src = NULL, dst, args [5];
4061 gboolean done = FALSE;
4065 LLVM_FAILURE (ctx, "!klass");
4069 if (mini_is_gsharedvt_klass (cfg, klass)) {
4071 LLVM_FAILURE (ctx, "gsharedvt");
4075 switch (ins->opcode) {
4076 case OP_STOREV_MEMBASE:
4077 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4078 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4079 /* Decomposed earlier */
4080 g_assert_not_reached ();
4083 if (!addresses [ins->sreg1]) {
4085 g_assert (values [ins->sreg1]);
4086 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));
4087 LLVMBuildStore (builder, values [ins->sreg1], dst);
4090 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4091 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4094 case OP_LOADV_MEMBASE:
4095 if (!addresses [ins->dreg])
4096 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4097 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4098 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4101 if (!addresses [ins->sreg1])
4102 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4103 if (!addresses [ins->dreg])
4104 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4105 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4106 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4109 g_assert_not_reached ();
4111 CHECK_FAILURE (ctx);
4118 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4119 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4121 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4122 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4123 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4126 case OP_LLVM_OUTARG_VT:
4127 if (!addresses [ins->sreg1]) {
4128 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4129 g_assert (values [ins->sreg1]);
4130 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4132 addresses [ins->dreg] = addresses [ins->sreg1];
4138 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4140 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4143 case OP_LOADX_MEMBASE: {
4144 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4147 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4148 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4151 case OP_STOREX_MEMBASE: {
4152 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4155 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4156 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4163 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4167 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4173 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4177 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4181 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4185 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4188 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4191 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4194 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4198 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4209 LLVMValueRef v = NULL;
4211 switch (ins->opcode) {
4216 t = LLVMVectorType (LLVMInt32Type (), 4);
4217 rt = LLVMVectorType (LLVMFloatType (), 4);
4223 t = LLVMVectorType (LLVMInt64Type (), 2);
4224 rt = LLVMVectorType (LLVMDoubleType (), 2);
4227 t = LLVMInt32Type ();
4228 rt = LLVMInt32Type ();
4229 g_assert_not_reached ();
4232 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4233 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4234 switch (ins->opcode) {
4237 v = LLVMBuildAnd (builder, lhs, rhs, "");
4241 v = LLVMBuildOr (builder, lhs, rhs, "");
4245 v = LLVMBuildXor (builder, lhs, rhs, "");
4249 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4252 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4276 case OP_PADDB_SAT_UN:
4277 case OP_PADDW_SAT_UN:
4278 case OP_PSUBB_SAT_UN:
4279 case OP_PSUBW_SAT_UN:
4287 case OP_PMULW_HIGH_UN: {
4288 LLVMValueRef args [2];
4293 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4300 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4304 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4312 case OP_EXTRACTX_U2:
4314 case OP_EXTRACT_U1: {
4316 gboolean zext = FALSE;
4318 t = simd_op_to_llvm_type (ins->opcode);
4320 switch (ins->opcode) {
4328 case OP_EXTRACTX_U2:
4333 t = LLVMInt32Type ();
4334 g_assert_not_reached ();
4337 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4338 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4340 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4349 case OP_EXPAND_R8: {
4350 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4351 LLVMValueRef mask [16], v;
4354 for (i = 0; i < 16; ++i)
4355 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4357 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4359 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4360 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4365 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4368 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4371 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4374 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4377 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4380 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4391 case OP_EXTRACT_MASK:
4398 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4400 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4406 LLVMValueRef args [3];
4410 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4412 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4417 /* This is only used for implementing shifts by non-immediate */
4418 values [ins->dreg] = lhs;
4429 LLVMValueRef args [3];
4432 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4434 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4445 case OP_PSHLQ_REG: {
4446 LLVMValueRef args [3];
4449 args [1] = values [ins->sreg2];
4451 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4458 case OP_PSHUFLEW_LOW:
4459 case OP_PSHUFLEW_HIGH: {
4461 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4462 int i, mask_size = 0;
4463 int imask = ins->inst_c0;
4465 /* Convert the x86 shuffle mask to LLVM's */
4466 switch (ins->opcode) {
4469 mask [0] = ((imask >> 0) & 3);
4470 mask [1] = ((imask >> 2) & 3);
4471 mask [2] = ((imask >> 4) & 3) + 4;
4472 mask [3] = ((imask >> 6) & 3) + 4;
4473 v1 = values [ins->sreg1];
4474 v2 = values [ins->sreg2];
4478 mask [0] = ((imask >> 0) & 1);
4479 mask [1] = ((imask >> 1) & 1) + 2;
4480 v1 = values [ins->sreg1];
4481 v2 = values [ins->sreg2];
4483 case OP_PSHUFLEW_LOW:
4485 mask [0] = ((imask >> 0) & 3);
4486 mask [1] = ((imask >> 2) & 3);
4487 mask [2] = ((imask >> 4) & 3);
4488 mask [3] = ((imask >> 6) & 3);
4493 v1 = values [ins->sreg1];
4494 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4496 case OP_PSHUFLEW_HIGH:
4502 mask [4] = 4 + ((imask >> 0) & 3);
4503 mask [5] = 4 + ((imask >> 2) & 3);
4504 mask [6] = 4 + ((imask >> 4) & 3);
4505 mask [7] = 4 + ((imask >> 6) & 3);
4506 v1 = values [ins->sreg1];
4507 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4511 mask [0] = ((imask >> 0) & 3);
4512 mask [1] = ((imask >> 2) & 3);
4513 mask [2] = ((imask >> 4) & 3);
4514 mask [3] = ((imask >> 6) & 3);
4515 v1 = values [ins->sreg1];
4516 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4519 g_assert_not_reached ();
4521 for (i = 0; i < mask_size; ++i)
4522 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4524 values [ins->dreg] =
4525 LLVMBuildShuffleVector (builder, v1, v2,
4526 LLVMConstVector (mask_values, mask_size), dname);
4530 case OP_UNPACK_LOWB:
4531 case OP_UNPACK_LOWW:
4532 case OP_UNPACK_LOWD:
4533 case OP_UNPACK_LOWQ:
4534 case OP_UNPACK_LOWPS:
4535 case OP_UNPACK_LOWPD:
4536 case OP_UNPACK_HIGHB:
4537 case OP_UNPACK_HIGHW:
4538 case OP_UNPACK_HIGHD:
4539 case OP_UNPACK_HIGHQ:
4540 case OP_UNPACK_HIGHPS:
4541 case OP_UNPACK_HIGHPD: {
4543 LLVMValueRef mask_values [16];
4544 int i, mask_size = 0;
4545 gboolean low = FALSE;
4547 switch (ins->opcode) {
4548 case OP_UNPACK_LOWB:
4552 case OP_UNPACK_LOWW:
4556 case OP_UNPACK_LOWD:
4557 case OP_UNPACK_LOWPS:
4561 case OP_UNPACK_LOWQ:
4562 case OP_UNPACK_LOWPD:
4566 case OP_UNPACK_HIGHB:
4569 case OP_UNPACK_HIGHW:
4572 case OP_UNPACK_HIGHD:
4573 case OP_UNPACK_HIGHPS:
4576 case OP_UNPACK_HIGHQ:
4577 case OP_UNPACK_HIGHPD:
4581 g_assert_not_reached ();
4585 for (i = 0; i < (mask_size / 2); ++i) {
4587 mask [(i * 2) + 1] = mask_size + i;
4590 for (i = 0; i < (mask_size / 2); ++i) {
4591 mask [(i * 2)] = (mask_size / 2) + i;
4592 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4596 for (i = 0; i < mask_size; ++i)
4597 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4599 values [ins->dreg] =
4600 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4601 LLVMConstVector (mask_values, mask_size), dname);
4606 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4607 LLVMValueRef v, val;
4609 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4610 val = LLVMConstNull (t);
4611 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4612 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4614 values [ins->dreg] = val;
4618 case OP_DUPPS_HIGH: {
4619 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4620 LLVMValueRef v1, v2, val;
4623 if (ins->opcode == OP_DUPPS_LOW) {
4624 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4625 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4627 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4628 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4630 val = LLVMConstNull (t);
4631 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4632 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4633 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4634 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4636 values [ins->dreg] = val;
4646 * EXCEPTION HANDLING
4648 case OP_IMPLICIT_EXCEPTION:
4649 /* This marks a place where an implicit exception can happen */
4650 if (bb->region != -1)
4651 LLVM_FAILURE (ctx, "implicit-exception");
4655 MonoMethodSignature *throw_sig;
4656 LLVMValueRef callee, arg;
4657 gboolean rethrow = (ins->opcode == OP_RETHROW);
4658 const char *icall_name;
4660 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4661 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4664 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4665 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4666 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4667 if (cfg->compile_aot) {
4668 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4670 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4674 * LLVM doesn't push the exception argument, so we need a different
4677 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4679 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4683 mono_memory_barrier ();
4685 ctx->lmodule->rethrow = callee;
4687 ctx->lmodule->throw = callee;
4689 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4690 emit_call (ctx, bb, &builder, callee, &arg, 1);
4693 case OP_CALL_HANDLER: {
4695 * We don't 'call' handlers, but instead simply branch to them.
4696 * The code generated by ENDFINALLY will branch back to us.
4698 LLVMBasicBlockRef noex_bb;
4700 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4702 bb_list = info->call_handler_return_bbs;
4705 * Set the indicator variable for the finally clause.
4707 lhs = info->finally_ind;
4709 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4711 /* Branch to the finally clause */
4712 LLVMBuildBr (builder, info->call_handler_target_bb);
4714 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4715 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4717 builder = ctx->builder = create_builder (ctx);
4718 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4720 bblocks [bb->block_num].end_bblock = noex_bb;
4723 case OP_START_HANDLER: {
4726 case OP_ENDFINALLY: {
4727 LLVMBasicBlockRef resume_bb;
4728 MonoBasicBlock *handler_bb;
4729 LLVMValueRef val, switch_ins, callee;
4733 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4734 g_assert (handler_bb);
4735 info = &bblocks [handler_bb->block_num];
4736 lhs = info->finally_ind;
4739 bb_list = info->call_handler_return_bbs;
4741 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4743 /* Load the finally variable */
4744 val = LLVMBuildLoad (builder, lhs, "");
4746 /* Reset the variable */
4747 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4749 /* Branch to either resume_bb, or to the bblocks in bb_list */
4750 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4752 * The other targets are added at the end to handle OP_CALL_HANDLER
4753 * opcodes processed later.
4755 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4757 builder = ctx->builder = create_builder (ctx);
4758 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4760 if (ctx->cfg->compile_aot) {
4761 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4763 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4765 LLVMBuildCall (builder, callee, NULL, 0, "");
4767 LLVMBuildUnreachable (builder);
4768 has_terminator = TRUE;
4774 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4775 LLVM_FAILURE (ctx, reason);
4780 /* Convert the value to the type required by phi nodes */
4781 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4782 if (!values [ins->dreg])
4784 values [ins->dreg] = addresses [ins->dreg];
4786 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4789 /* Add stores for volatile variables */
4790 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4791 emit_volatile_store (ctx, ins->dreg);
4794 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4795 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4797 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4798 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4799 LLVMBuildRetVoid (builder);
4802 if (bb == cfg->bb_entry)
4803 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4812 * mono_llvm_check_method_supported:
4814 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4815 * compiling a method twice.
4818 mono_llvm_check_method_supported (MonoCompile *cfg)
4822 if (cfg->method->save_lmf) {
4823 cfg->exception_message = g_strdup ("lmf");
4824 cfg->disable_llvm = TRUE;
4826 if (cfg->disable_llvm)
4830 * Nested clauses where one of the clauses is a finally clause is
4831 * not supported, because LLVM can't figure out the control flow,
4832 * probably because we resume exception handling by calling our
4833 * own function instead of using the 'resume' llvm instruction.
4835 for (i = 0; i < cfg->header->num_clauses; ++i) {
4836 for (j = 0; j < cfg->header->num_clauses; ++j) {
4837 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4838 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4840 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4841 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4842 cfg->exception_message = g_strdup ("nested clauses");
4843 cfg->disable_llvm = TRUE;
4848 if (cfg->disable_llvm)
4852 if (cfg->method->dynamic) {
4853 cfg->exception_message = g_strdup ("dynamic.");
4854 cfg->disable_llvm = TRUE;
4856 if (cfg->disable_llvm)
4861 * mono_llvm_emit_method:
4863 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4866 mono_llvm_emit_method (MonoCompile *cfg)
4869 MonoMethodSignature *sig;
4871 LLVMTypeRef method_type;
4872 LLVMValueRef method = NULL;
4874 LLVMValueRef *values;
4875 int i, max_block_num, bb_index;
4876 gboolean last = FALSE;
4877 GPtrArray *phi_values;
4878 LLVMCallInfo *linfo;
4880 LLVMModuleRef module;
4882 GPtrArray *bblock_list;
4883 MonoMethodHeader *header;
4884 MonoExceptionClause *clause;
4888 /* The code below might acquire the loader lock, so use it for global locking */
4889 mono_loader_lock ();
4891 /* Used to communicate with the callbacks */
4892 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4894 ctx = g_new0 (EmitContext, 1);
4896 ctx->mempool = cfg->mempool;
4899 * This maps vregs to the LLVM instruction defining them
4901 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4903 * This maps vregs for volatile variables to the LLVM instruction defining their
4906 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4907 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4908 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4909 phi_values = g_ptr_array_sized_new (256);
4911 * This signals whenever the vreg was defined by a phi node with no input vars
4912 * (i.e. all its input bblocks end with NOT_REACHABLE).
4914 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4915 /* Whenever the bblock is unreachable */
4916 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4918 bblock_list = g_ptr_array_sized_new (256);
4920 ctx->values = values;
4921 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4922 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4924 if (cfg->compile_aot) {
4925 ctx->lmodule = &aot_module;
4926 method_name = mono_aot_get_method_name (cfg);
4927 cfg->llvm_method_name = g_strdup (method_name);
4929 init_jit_module (cfg->domain);
4930 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4931 method_name = mono_method_full_name (cfg->method, TRUE);
4934 module = ctx->module = ctx->lmodule->module;
4937 LLVM_FAILURE (ctx, "gsharedvt");
4941 static int count = 0;
4944 if (g_getenv ("LLVM_COUNT")) {
4945 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4946 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4950 if (count > atoi (g_getenv ("LLVM_COUNT")))
4951 LLVM_FAILURE (ctx, "");
4956 sig = mono_method_signature (cfg->method);
4959 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4961 CHECK_FAILURE (ctx);
4964 linfo->rgctx_arg = TRUE;
4965 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4966 CHECK_FAILURE (ctx);
4969 * This maps parameter indexes in the original signature to the indexes in
4970 * the LLVM signature.
4972 ctx->pindexes = sinfo.pindexes;
4974 method = LLVMAddFunction (module, method_name, method_type);
4975 ctx->lmethod = method;
4977 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4978 LLVMSetLinkage (method, LLVMPrivateLinkage);
4980 LLVMAddFunctionAttr (method, LLVMUWTable);
4982 if (cfg->compile_aot) {
4983 LLVMSetLinkage (method, LLVMInternalLinkage);
4984 if (ctx->lmodule->external_symbols) {
4985 LLVMSetLinkage (method, LLVMExternalLinkage);
4986 LLVMSetVisibility (method, LLVMHiddenVisibility);
4989 LLVMSetLinkage (method, LLVMPrivateLinkage);
4992 if (cfg->method->save_lmf)
4993 LLVM_FAILURE (ctx, "lmf");
4995 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4996 LLVM_FAILURE (ctx, "pinvoke signature");
4998 header = cfg->header;
4999 for (i = 0; i < header->num_clauses; ++i) {
5000 clause = &header->clauses [i];
5001 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5002 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5004 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5005 /* We can't handle inlined methods with clauses */
5006 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5008 if (linfo->rgctx_arg) {
5009 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5011 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5012 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5013 * CC_X86_64_Mono in X86CallingConv.td.
5015 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5016 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5018 if (cfg->vret_addr) {
5019 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5020 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5023 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5024 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5027 names = g_new (char *, sig->param_count);
5028 mono_method_get_param_names (cfg->method, (const char **) names);
5030 for (i = 0; i < sig->param_count; ++i) {
5033 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5034 if (names [i] && names [i][0] != '\0')
5035 name = g_strdup_printf ("arg_%s", names [i]);
5037 name = g_strdup_printf ("arg_%d", i);
5038 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5040 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5041 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5045 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5046 ctx->minfo = mono_debug_lookup_method (cfg->method);
5047 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5051 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5052 max_block_num = MAX (max_block_num, bb->block_num);
5053 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5055 /* Add branches between non-consecutive bblocks */
5056 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5057 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5058 bb->next_bb != bb->last_ins->inst_false_bb) {
5060 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5061 inst->opcode = OP_BR;
5062 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5063 mono_bblock_add_inst (bb, inst);
5068 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5069 * was later optimized away, so clear these flags, and add them back for the still
5070 * present OP_LDADDR instructions.
5072 for (i = 0; i < cfg->next_vreg; ++i) {
5075 ins = get_vreg_to_inst (cfg, i);
5076 if (ins && ins != cfg->rgctx_var)
5077 ins->flags &= ~MONO_INST_INDIRECT;
5081 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5083 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5085 LLVMBuilderRef builder;
5087 char dname_buf[128];
5089 builder = create_builder (ctx);
5091 for (ins = bb->code; ins; ins = ins->next) {
5092 switch (ins->opcode) {
5097 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5099 CHECK_FAILURE (ctx);
5101 if (ins->opcode == OP_VPHI) {
5102 /* Treat valuetype PHI nodes as operating on the address itself */
5103 g_assert (ins->klass);
5104 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5108 * Have to precreate these, as they can be referenced by
5109 * earlier instructions.
5111 sprintf (dname_buf, "t%d", ins->dreg);
5113 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5115 if (ins->opcode == OP_VPHI)
5116 ctx->addresses [ins->dreg] = values [ins->dreg];
5118 g_ptr_array_add (phi_values, values [ins->dreg]);
5121 * Set the expected type of the incoming arguments since these have
5122 * to have the same type.
5124 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5125 int sreg1 = ins->inst_phi_args [i + 1];
5128 ctx->vreg_types [sreg1] = phi_type;
5133 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5142 * Create an ordering for bblocks, use the depth first order first, then
5143 * put the exception handling bblocks last.
5145 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5146 bb = cfg->bblocks [bb_index];
5147 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5148 g_ptr_array_add (bblock_list, bb);
5149 bblocks [bb->block_num].added = TRUE;
5153 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5154 if (!bblocks [bb->block_num].added)
5155 g_ptr_array_add (bblock_list, bb);
5159 * Second pass: generate code.
5161 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5162 bb = g_ptr_array_index (bblock_list, bb_index);
5164 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5167 process_bb (ctx, bb);
5168 CHECK_FAILURE (ctx);
5171 /* Add incoming phi values */
5172 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5173 GSList *l, *ins_list;
5175 ins_list = bblocks [bb->block_num].phi_nodes;
5177 for (l = ins_list; l; l = l->next) {
5178 PhiNode *node = l->data;
5179 MonoInst *phi = node->phi;
5180 int sreg1 = node->sreg;
5181 LLVMBasicBlockRef in_bb;
5186 in_bb = get_end_bb (ctx, node->in_bb);
5188 if (ctx->unreachable [node->in_bb->block_num])
5191 if (!values [sreg1])
5192 /* Can happen with values in EH clauses */
5193 LLVM_FAILURE (ctx, "incoming phi sreg1");
5195 if (phi->opcode == OP_VPHI) {
5196 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5197 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5199 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5201 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5202 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5203 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5208 /* Create the SWITCH statements for ENDFINALLY instructions */
5209 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5210 BBInfo *info = &bblocks [bb->block_num];
5212 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5213 LLVMValueRef switch_ins = l->data;
5214 GSList *bb_list = info->call_handler_return_bbs;
5216 for (i = 0; i < g_slist_length (bb_list); ++i)
5217 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5221 if (cfg->verbose_level > 1)
5222 mono_llvm_dump_value (method);
5224 if (cfg->compile_aot)
5225 mark_as_used (ctx->lmodule, method);
5227 if (cfg->compile_aot) {
5228 LLVMValueRef md_args [16];
5229 LLVMValueRef md_node;
5232 method_index = mono_aot_get_method_index (cfg->orig_method);
5233 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5234 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5235 md_node = LLVMMDNode (md_args, 2);
5236 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5237 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5240 if (cfg->compile_aot) {
5241 /* Don't generate native code, keep the LLVM IR */
5242 if (cfg->compile_aot && cfg->verbose_level)
5243 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5245 //LLVMVerifyFunction(method, 0);
5247 //LLVMVerifyFunction(method, 0);
5248 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5250 if (cfg->verbose_level > 1)
5251 mono_llvm_dump_value (method);
5253 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5255 /* Set by emit_cb */
5256 g_assert (cfg->code_len);
5258 /* FIXME: Free the LLVM IL for the function */
5261 if (ctx->lmodule->method_to_lmethod)
5262 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5269 /* Need to add unused phi nodes as they can be referenced by other values */
5270 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5271 LLVMBuilderRef builder;
5273 builder = create_builder (ctx);
5274 LLVMPositionBuilderAtEnd (builder, phi_bb);
5276 for (i = 0; i < phi_values->len; ++i) {
5277 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5278 if (LLVMGetInstructionParent (v) == NULL)
5279 LLVMInsertIntoBuilder (builder, v);
5282 LLVMDeleteFunction (method);
5287 g_free (ctx->addresses);
5288 g_free (ctx->vreg_types);
5289 g_free (ctx->vreg_cli_types);
5290 g_free (ctx->pindexes);
5291 g_free (ctx->is_dead);
5292 g_free (ctx->unreachable);
5293 g_ptr_array_free (phi_values, TRUE);
5294 g_free (ctx->bblocks);
5295 g_hash_table_destroy (ctx->region_to_handler);
5296 g_hash_table_destroy (ctx->clause_to_handler);
5297 g_free (method_name);
5298 g_ptr_array_free (bblock_list, TRUE);
5300 for (l = ctx->builders; l; l = l->next) {
5301 LLVMBuilderRef builder = l->data;
5302 LLVMDisposeBuilder (builder);
5307 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5309 mono_loader_unlock ();
5313 * mono_llvm_emit_call:
5315 * Same as mono_arch_emit_call () for LLVM.
5318 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5321 MonoMethodSignature *sig;
5322 int i, n, stack_size;
5327 sig = call->signature;
5328 n = sig->param_count + sig->hasthis;
5330 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5332 if (cfg->disable_llvm)
5335 if (sig->call_convention == MONO_CALL_VARARG) {
5336 cfg->exception_message = g_strdup ("varargs");
5337 cfg->disable_llvm = TRUE;
5340 for (i = 0; i < n; ++i) {
5343 ainfo = call->cinfo->args + i;
5345 in = call->args [i];
5347 /* Simply remember the arguments */
5348 switch (ainfo->storage) {
5350 case LLVMArgInFPReg: {
5351 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5354 opcode = mono_type_to_regmove (cfg, t);
5355 if (opcode == OP_FMOVE) {
5356 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5357 ins->dreg = mono_alloc_freg (cfg);
5358 } else if (opcode == OP_LMOVE) {
5359 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5360 ins->dreg = mono_alloc_lreg (cfg);
5362 MONO_INST_NEW (cfg, ins, OP_MOVE);
5363 ins->dreg = mono_alloc_ireg (cfg);
5365 ins->sreg1 = in->dreg;
5368 case LLVMArgVtypeByVal:
5369 case LLVMArgVtypeInReg:
5370 case LLVMArgAsIArgs:
5371 case LLVMArgAsFpArgs:
5372 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5373 ins->dreg = mono_alloc_ireg (cfg);
5374 ins->sreg1 = in->dreg;
5375 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5378 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5379 cfg->exception_message = g_strdup ("ainfo->storage");
5380 cfg->disable_llvm = TRUE;
5384 if (!cfg->disable_llvm) {
5385 MONO_ADD_INS (cfg->cbb, ins);
5386 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5391 static unsigned char*
5392 alloc_cb (LLVMValueRef function, int size)
5396 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5400 return mono_domain_code_reserve (cfg->domain, size);
5402 return mono_domain_code_reserve (mono_domain_get (), size);
5407 emitted_cb (LLVMValueRef function, void *start, void *end)
5411 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5413 cfg->code_len = (guint8*)end - (guint8*)start;
5417 exception_cb (void *data)
5420 MonoJitExceptionInfo *ei;
5421 guint32 ei_len, i, j, nested_len, nindex;
5422 gpointer *type_info;
5423 int this_reg, this_offset;
5425 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5429 * data points to a DWARF FDE structure, convert it to our unwind format and
5431 * An alternative would be to save it directly, and modify our unwinder to work
5434 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);
5435 if (cfg->verbose_level > 1)
5436 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5438 /* Count nested clauses */
5440 for (i = 0; i < ei_len; ++i) {
5441 for (j = 0; j < ei_len; ++j) {
5442 gint32 cindex1 = *(gint32*)type_info [i];
5443 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5444 gint32 cindex2 = *(gint32*)type_info [j];
5445 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5447 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5453 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5454 cfg->llvm_ex_info_len = ei_len + nested_len;
5455 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5456 /* Fill the rest of the information from the type info */
5457 for (i = 0; i < ei_len; ++i) {
5458 gint32 clause_index = *(gint32*)type_info [i];
5459 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5461 cfg->llvm_ex_info [i].flags = clause->flags;
5462 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5463 cfg->llvm_ex_info [i].clause_index = clause_index;
5467 * For nested clauses, the LLVM produced exception info associates the try interval with
5468 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5469 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5470 * and everything else from the nested clause.
5473 for (i = 0; i < ei_len; ++i) {
5474 for (j = 0; j < ei_len; ++j) {
5475 gint32 cindex1 = *(gint32*)type_info [i];
5476 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5477 gint32 cindex2 = *(gint32*)type_info [j];
5478 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5480 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5481 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5482 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5483 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5484 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5485 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5490 g_assert (nindex == ei_len + nested_len);
5491 cfg->llvm_this_reg = this_reg;
5492 cfg->llvm_this_offset = this_offset;
5494 /* type_info [i] is cfg mempool allocated, no need to free it */
5501 dlsym_cb (const char *name, void **symbol)
5507 if (!strcmp (name, "__bzero")) {
5508 *symbol = (void*)bzero;
5510 current = mono_dl_open (NULL, 0, NULL);
5513 err = mono_dl_symbol (current, name, symbol);
5515 mono_dl_close (current);
5517 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5518 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5524 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5526 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5530 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5532 LLVMTypeRef param_types [4];
5534 param_types [0] = param_type1;
5535 param_types [1] = param_type2;
5537 AddFunc (module, name, ret_type, param_types, 2);
5541 add_intrinsics (LLVMModuleRef module)
5543 /* Emit declarations of instrinsics */
5545 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5546 * type doesn't seem to do any locking.
5549 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5551 memset_param_count = 5;
5552 memset_func_name = "llvm.memset.p0i8.i32";
5554 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5558 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5560 memcpy_param_count = 5;
5561 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5563 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5567 LLVMTypeRef params [] = { LLVMDoubleType () };
5569 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5570 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5571 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5573 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5574 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5578 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5579 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5580 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5582 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5583 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5584 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5585 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5586 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5587 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5588 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5592 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5593 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5594 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5596 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5597 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5598 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5599 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5600 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5601 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5606 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5608 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5611 /* SSE intrinsics */
5612 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5614 LLVMTypeRef ret_type, arg_types [16];
5617 ret_type = type_to_simd_type (MONO_TYPE_I4);
5618 arg_types [0] = ret_type;
5619 arg_types [1] = ret_type;
5620 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5621 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5623 ret_type = type_to_simd_type (MONO_TYPE_I2);
5624 arg_types [0] = ret_type;
5625 arg_types [1] = ret_type;
5626 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5627 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5628 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5629 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5630 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5631 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5633 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5637 ret_type = type_to_simd_type (MONO_TYPE_I1);
5638 arg_types [0] = ret_type;
5639 arg_types [1] = ret_type;
5640 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5641 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5642 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5643 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5644 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5645 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5648 ret_type = type_to_simd_type (MONO_TYPE_R8);
5649 arg_types [0] = ret_type;
5650 arg_types [1] = ret_type;
5651 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5652 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5653 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5654 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5655 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5657 ret_type = type_to_simd_type (MONO_TYPE_R4);
5658 arg_types [0] = ret_type;
5659 arg_types [1] = ret_type;
5660 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5661 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5662 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5663 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5664 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5667 ret_type = type_to_simd_type (MONO_TYPE_I1);
5668 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5669 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5670 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5671 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5672 ret_type = type_to_simd_type (MONO_TYPE_I2);
5673 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5674 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5675 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5676 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5679 ret_type = type_to_simd_type (MONO_TYPE_R8);
5680 arg_types [0] = ret_type;
5681 arg_types [1] = ret_type;
5682 arg_types [2] = LLVMInt8Type ();
5683 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5684 ret_type = type_to_simd_type (MONO_TYPE_R4);
5685 arg_types [0] = ret_type;
5686 arg_types [1] = ret_type;
5687 arg_types [2] = LLVMInt8Type ();
5688 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5690 /* Conversion ops */
5691 ret_type = type_to_simd_type (MONO_TYPE_R8);
5692 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5693 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5694 ret_type = type_to_simd_type (MONO_TYPE_R4);
5695 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5696 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5697 ret_type = type_to_simd_type (MONO_TYPE_I4);
5698 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5699 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5700 ret_type = type_to_simd_type (MONO_TYPE_I4);
5701 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5702 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5703 ret_type = type_to_simd_type (MONO_TYPE_R4);
5704 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5705 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5706 ret_type = type_to_simd_type (MONO_TYPE_R8);
5707 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5708 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5710 ret_type = type_to_simd_type (MONO_TYPE_I4);
5711 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5712 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5713 ret_type = type_to_simd_type (MONO_TYPE_I4);
5714 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5715 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5718 ret_type = type_to_simd_type (MONO_TYPE_R8);
5719 arg_types [0] = ret_type;
5720 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5721 ret_type = type_to_simd_type (MONO_TYPE_R4);
5722 arg_types [0] = ret_type;
5723 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5724 ret_type = type_to_simd_type (MONO_TYPE_R4);
5725 arg_types [0] = ret_type;
5726 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5727 ret_type = type_to_simd_type (MONO_TYPE_R4);
5728 arg_types [0] = ret_type;
5729 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5732 ret_type = type_to_simd_type (MONO_TYPE_I2);
5733 arg_types [0] = ret_type;
5734 arg_types [1] = LLVMInt32Type ();
5735 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5736 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5737 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5738 ret_type = type_to_simd_type (MONO_TYPE_I4);
5739 arg_types [0] = ret_type;
5740 arg_types [1] = LLVMInt32Type ();
5741 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5742 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5743 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5744 ret_type = type_to_simd_type (MONO_TYPE_I8);
5745 arg_types [0] = ret_type;
5746 arg_types [1] = LLVMInt32Type ();
5747 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5748 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5751 ret_type = LLVMInt32Type ();
5752 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5753 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5756 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5759 /* Load/Store intrinsics */
5761 LLVMTypeRef arg_types [5];
5765 for (i = 1; i <= 8; i *= 2) {
5766 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5767 arg_types [1] = LLVMInt32Type ();
5768 arg_types [2] = LLVMInt1Type ();
5769 arg_types [3] = LLVMInt32Type ();
5770 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5771 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5773 arg_types [0] = LLVMIntType (i * 8);
5774 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5775 arg_types [2] = LLVMInt32Type ();
5776 arg_types [3] = LLVMInt1Type ();
5777 arg_types [4] = LLVMInt32Type ();
5778 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5779 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5785 add_types (MonoLLVMModule *lmodule)
5787 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5791 mono_llvm_init (void)
5793 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5797 init_jit_module (MonoDomain *domain)
5799 MonoJitICallInfo *info;
5800 MonoJitDomainInfo *dinfo;
5801 MonoLLVMModule *module;
5804 dinfo = domain_jit_info (domain);
5805 if (dinfo->llvm_module)
5808 mono_loader_lock ();
5810 if (dinfo->llvm_module) {
5811 mono_loader_unlock ();
5815 module = g_new0 (MonoLLVMModule, 1);
5817 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5818 module->module = LLVMModuleCreateWithName (name);
5820 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5822 add_intrinsics (module->module);
5825 module->llvm_types = g_hash_table_new (NULL, NULL);
5827 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5829 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5831 mono_memory_barrier ();
5833 dinfo->llvm_module = module;
5835 mono_loader_unlock ();
5839 mono_llvm_cleanup (void)
5841 if (aot_module.module)
5842 LLVMDisposeModule (aot_module.module);
5844 LLVMContextDispose (LLVMGetGlobalContext ());
5848 mono_llvm_free_domain_info (MonoDomain *domain)
5850 MonoJitDomainInfo *info = domain_jit_info (domain);
5851 MonoLLVMModule *module = info->llvm_module;
5857 if (module->llvm_types)
5858 g_hash_table_destroy (module->llvm_types);
5860 mono_llvm_dispose_ee (module->mono_ee);
5862 if (module->bb_names) {
5863 for (i = 0; i < module->bb_names_len; ++i)
5864 g_free (module->bb_names [i]);
5865 g_free (module->bb_names);
5867 //LLVMDisposeModule (module->module);
5871 info->llvm_module = NULL;
5875 mono_llvm_create_aot_module (const char *global_prefix, gboolean emit_dwarf)
5877 /* Delete previous module */
5878 if (aot_module.plt_entries)
5879 g_hash_table_destroy (aot_module.plt_entries);
5880 if (aot_module.module)
5881 LLVMDisposeModule (aot_module.module);
5883 memset (&aot_module, 0, sizeof (aot_module));
5885 aot_module.module = LLVMModuleCreateWithName ("aot");
5886 aot_module.got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
5887 aot_module.eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
5888 aot_module.external_symbols = TRUE;
5889 aot_module.emit_dwarf = emit_dwarf;
5890 /* The first few entries are reserved */
5891 aot_module.max_got_offset = 16;
5893 add_intrinsics (aot_module.module);
5894 add_types (&aot_module);
5898 * We couldn't compute the type of the LLVM global representing the got because
5899 * its size is only known after all the methods have been emitted. So create
5900 * a dummy variable, and replace all uses it with the real got variable when
5901 * its size is known in mono_llvm_emit_aot_module ().
5904 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5906 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5907 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5910 /* Add a dummy personality function */
5912 LLVMBasicBlockRef lbb;
5913 LLVMBuilderRef lbuilder;
5914 LLVMValueRef personality;
5916 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5917 LLVMSetLinkage (personality, LLVMInternalLinkage);
5918 lbb = LLVMAppendBasicBlock (personality, "BB0");
5919 lbuilder = LLVMCreateBuilder ();
5920 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5921 LLVMBuildRetVoid (lbuilder);
5922 mark_as_used (&aot_module, personality);
5925 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5926 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5927 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5928 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5932 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
5935 LLVMValueRef res, *vals;
5937 vals = g_new0 (LLVMValueRef, nvalues);
5938 for (i = 0; i < nvalues; ++i)
5939 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
5940 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
5946 * mono_llvm_emit_aot_file_info:
5948 * Emit the MonoAotFileInfo structure.
5949 * Same as emit_aot_file_info () in aot-compiler.c.
5952 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
5954 /* Save these for later */
5955 memcpy (&aot_module.aot_info, info, sizeof (MonoAotFileInfo));
5956 aot_module.has_jitted_code = has_jitted_code;
5960 * mono_llvm_emit_aot_data:
5962 * Emit the binary data DATA pointed to by symbol SYMBOL.
5965 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
5967 MonoLLVMModule *lmodule = &aot_module;
5971 type = LLVMArrayType (LLVMInt8Type (), data_len);
5972 d = LLVMAddGlobal (lmodule->module, type, symbol);
5973 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
5977 emit_aot_file_info (MonoLLVMModule *lmodule)
5979 LLVMTypeRef file_info_type;
5980 LLVMTypeRef *eltypes, eltype;
5981 LLVMValueRef info_var;
5982 LLVMValueRef *fields;
5983 int i, nfields, tindex;
5984 MonoAotFileInfo *info;
5986 info = &lmodule->aot_info;
5988 /* Create an LLVM type to represent MonoAotFileInfo */
5990 eltypes = g_new (LLVMTypeRef, nfields);
5992 eltypes [tindex ++] = LLVMInt32Type ();
5993 eltypes [tindex ++] = LLVMInt32Type ();
5995 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
5996 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
5998 for (i = 0; i < 13; ++i)
5999 eltypes [tindex ++] = LLVMInt32Type ();
6001 for (i = 0; i < 4; ++i)
6002 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
6003 g_assert (tindex == nfields);
6004 file_info_type = LLVMStructCreateNamed (LLVMGetGlobalContext (), "MonoAotFileInfo");
6005 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
6007 info_var = LLVMAddGlobal (aot_module.module, file_info_type, "mono_aot_file_info");
6008 fields = g_new (LLVMValueRef, nfields);
6010 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
6011 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
6015 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
6016 * for symbols defined in the .s file emitted by the aot compiler.
6018 eltype = eltypes [tindex];
6019 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "jit_got");
6020 fields [tindex ++] = aot_module.got_var;
6021 /* llc defines this directly */
6022 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, aot_module.eh_frame_symbol);
6023 if (TRUE || aot_module.has_jitted_code) {
6024 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "jit_code_start");
6025 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "jit_code_end");
6026 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "method_addresses");
6028 fields [tindex ++] = LLVMConstNull (eltype);
6029 fields [tindex ++] = LLVMConstNull (eltype);
6030 fields [tindex ++] = LLVMConstNull (eltype);
6032 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "blob");
6033 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "class_name_table");
6034 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "class_info_offsets");
6035 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "method_info_offsets");
6036 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "ex_info_offsets");
6037 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "extra_method_info_offsets");
6038 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "extra_method_table");
6039 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "got_info_offsets");
6040 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "llvm_got_info_offsets");
6041 /* Not needed (mem_end) */
6042 fields [tindex ++] = LLVMConstNull (eltype);
6043 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "image_table");
6044 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "assembly_guid");
6045 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "runtime_version");
6046 if (info->trampoline_size [0]) {
6047 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "specific_trampolines");
6048 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "static_rgctx_trampolines");
6049 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "imt_thunks");
6050 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "gsharedvt_arg_trampolines");
6052 fields [tindex ++] = LLVMConstNull (eltype);
6053 fields [tindex ++] = LLVMConstNull (eltype);
6054 fields [tindex ++] = LLVMConstNull (eltype);
6055 fields [tindex ++] = LLVMConstNull (eltype);
6058 fields [tindex ++] = LLVMConstNull (eltype);
6059 fields [tindex ++] = LLVMGetNamedGlobal (aot_module.module, "assembly_name");
6060 if (TRUE || aot_module.has_jitted_code) {
6061 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "plt");
6062 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "plt_end");
6063 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "unwind_info");
6064 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "unbox_trampolines");
6065 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "unbox_trampolines_end");
6066 fields [tindex ++] = LLVMAddGlobal (aot_module.module, eltype, "unbox_trampoline_addresses");
6068 fields [tindex ++] = LLVMConstNull (eltype);
6069 fields [tindex ++] = LLVMConstNull (eltype);
6070 fields [tindex ++] = LLVMConstNull (eltype);
6071 fields [tindex ++] = LLVMConstNull (eltype);
6072 fields [tindex ++] = LLVMConstNull (eltype);
6073 fields [tindex ++] = LLVMConstNull (eltype);
6077 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
6078 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
6079 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
6080 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
6081 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
6082 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
6083 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
6084 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
6085 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
6086 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
6087 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
6088 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
6089 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
6091 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
6092 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
6093 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
6094 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
6095 g_assert (tindex == nfields);
6097 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
6101 * Emit the aot module into the LLVM bitcode file FILENAME.
6104 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
6106 LLVMTypeRef got_type;
6107 LLVMValueRef real_got;
6108 MonoLLVMModule *module = &aot_module;
6111 * Create the real got variable and replace all uses of the dummy variable with
6114 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
6115 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
6116 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
6117 if (module->external_symbols) {
6118 LLVMSetLinkage (real_got, LLVMExternalLinkage);
6119 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
6121 LLVMSetLinkage (real_got, LLVMInternalLinkage);
6123 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6125 mark_as_used (&aot_module, real_got);
6127 /* Delete the dummy got so it doesn't become a global */
6128 LLVMDeleteGlobal (aot_module.got_var);
6129 aot_module.got_var = real_got;
6131 emit_llvm_used (&aot_module);
6132 emit_dbg_info (&aot_module, filename, cu_name);
6133 emit_aot_file_info (&aot_module);
6135 /* Replace PLT entries for directly callable methods with the methods themselves */
6137 GHashTableIter iter;
6139 LLVMValueRef callee;
6141 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6142 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6143 if (mono_aot_is_direct_callable (ji)) {
6144 LLVMValueRef lmethod;
6146 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6147 /* The types might not match because the caller might pass an rgctx */
6148 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6149 mono_llvm_replace_uses_of (callee, lmethod);
6150 mono_aot_mark_unused_llvm_plt_entry (ji);
6160 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6161 g_assert_not_reached ();
6166 LLVMWriteBitcodeToFile (aot_module.module, filename);
6171 md_string (const char *s)
6173 return LLVMMDString (s, strlen (s));
6176 /* Debugging support */
6179 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6181 LLVMModuleRef module = lmodule->module;
6182 LLVMValueRef args [16], cu_args [16], cu, ver;
6184 char *build_info, *s, *dir;
6187 * This can only be enabled when LLVM code is emitted into a separate object
6188 * file, since the AOT compiler also emits dwarf info,
6189 * and the abbrev indexes will not be correct since llvm has added its own
6192 if (!lmodule->emit_dwarf)
6196 * Emit dwarf info in the form of LLVM metadata. There is some
6197 * out-of-date documentation at:
6198 * http://llvm.org/docs/SourceLevelDebugging.html
6199 * but most of this was gathered from the llvm and
6204 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6205 /* CU name/compilation dir */
6206 dir = g_path_get_dirname (filename);
6207 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6208 args [1] = LLVMMDString (dir, strlen (dir));
6209 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6212 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6214 build_info = mono_get_runtime_build_info ();
6215 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6216 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6217 g_free (build_info);
6219 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6221 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6222 /* Runtime version */
6223 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6225 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6226 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6228 if (lmodule->subprogram_mds) {
6232 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6233 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6234 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6235 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6237 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6240 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6241 /* Imported modules */
6242 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6244 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6245 /* DebugEmissionKind = FullDebug */
6246 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6247 cu = LLVMMDNode (cu_args, n_cuargs);
6248 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6250 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6251 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6252 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6253 ver = LLVMMDNode (args, 3);
6254 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6256 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6257 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6258 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6259 ver = LLVMMDNode (args, 3);
6260 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6264 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6266 MonoLLVMModule *module = ctx->lmodule;
6267 MonoDebugMethodInfo *minfo = ctx->minfo;
6268 char *source_file, *dir, *filename;
6269 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6270 MonoSymSeqPoint *sym_seq_points;
6276 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6278 source_file = g_strdup ("<unknown>");
6279 dir = g_path_get_dirname (source_file);
6280 filename = g_path_get_basename (source_file);
6282 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6283 args [0] = md_string (filename);
6284 args [1] = md_string (dir);
6285 ctx_args [1] = LLVMMDNode (args, 2);
6286 ctx_md = LLVMMDNode (ctx_args, 2);
6288 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6289 type_args [1] = NULL;
6290 type_args [2] = NULL;
6291 type_args [3] = LLVMMDString ("", 0);
6292 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6293 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6294 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6295 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6296 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6297 type_args [9] = NULL;
6298 type_args [10] = NULL;
6299 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6300 type_args [12] = NULL;
6301 type_args [13] = NULL;
6302 type_args [14] = NULL;
6303 type_md = LLVMMDNode (type_args, 14);
6305 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6306 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6307 /* Source directory + file pair */
6308 args [0] = md_string (filename);
6309 args [1] = md_string (dir);
6310 md_args [1] = LLVMMDNode (args ,2);
6311 md_args [2] = ctx_md;
6312 md_args [3] = md_string (cfg->method->name);
6313 md_args [4] = md_string (name);
6314 md_args [5] = md_string (name);
6317 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6319 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6321 md_args [7] = type_md;
6323 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6325 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6327 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6328 /* Index into a virtual function */
6329 md_args [11] = NULL;
6330 md_args [12] = NULL;
6332 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6334 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6335 /* Pointer to LLVM function */
6336 md_args [15] = method;
6337 /* Function template parameter */
6338 md_args [16] = NULL;
6339 /* Function declaration descriptor */
6340 md_args [17] = NULL;
6341 /* List of function variables */
6342 md_args [18] = LLVMMDNode (args, 0);
6344 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6345 md = LLVMMDNode (md_args, 20);
6347 if (!module->subprogram_mds)
6348 module->subprogram_mds = g_ptr_array_new ();
6349 g_ptr_array_add (module->subprogram_mds, md);
6353 g_free (source_file);
6354 g_free (sym_seq_points);
6360 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6362 MonoCompile *cfg = ctx->cfg;
6364 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6365 MonoDebugSourceLocation *loc;
6366 LLVMValueRef loc_md, md_args [16];
6369 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6373 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6374 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6375 md_args [nmd_args ++] = ctx->dbg_md;
6376 md_args [nmd_args ++] = NULL;
6377 loc_md = LLVMMDNode (md_args, nmd_args);
6378 LLVMSetCurrentDebugLocation (builder, loc_md);
6379 mono_debug_symfile_free_location (loc);
6386 - Emit LLVM IR from the mono IR using the LLVM C API.
6387 - The original arch specific code remains, so we can fall back to it if we run
6388 into something we can't handle.
6392 A partial list of issues:
6393 - Handling of opcodes which can throw exceptions.
6395 In the mono JIT, these are implemented using code like this:
6402 push throw_pos - method
6403 call <exception trampoline>
6405 The problematic part is push throw_pos - method, which cannot be represented
6406 in the LLVM IR, since it does not support label values.
6407 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6408 be implemented in JIT mode ?
6409 -> a possible but slower implementation would use the normal exception
6410 throwing code but it would need to control the placement of the throw code
6411 (it needs to be exactly after the compare+branch).
6412 -> perhaps add a PC offset intrinsics ?
6414 - efficient implementation of .ovf opcodes.
6416 These are currently implemented as:
6417 <ins which sets the condition codes>
6420 Some overflow opcodes are now supported by LLVM SVN.
6422 - exception handling, unwinding.
6423 - SSA is disabled for methods with exception handlers
6424 - How to obtain unwind info for LLVM compiled methods ?
6425 -> this is now solved by converting the unwind info generated by LLVM
6427 - LLVM uses the c++ exception handling framework, while we use our home grown
6428 code, and couldn't use the c++ one:
6429 - its not supported under VC++, other exotic platforms.
6430 - it might be impossible to support filter clauses with it.
6434 The trampolines need a predictable call sequence, since they need to disasm
6435 the calling code to obtain register numbers / offsets.
6437 LLVM currently generates this code in non-JIT mode:
6438 mov -0x98(%rax),%eax
6440 Here, the vtable pointer is lost.
6441 -> solution: use one vtable trampoline per class.
6443 - passing/receiving the IMT pointer/RGCTX.
6444 -> solution: pass them as normal arguments ?
6448 LLVM does not allow the specification of argument registers etc. This means
6449 that all calls are made according to the platform ABI.
6451 - passing/receiving vtypes.
6453 Vtypes passed/received in registers are handled by the front end by using
6454 a signature with scalar arguments, and loading the parts of the vtype into those
6457 Vtypes passed on the stack are handled using the 'byval' attribute.
6461 Supported though alloca, we need to emit the load/store code.
6465 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6466 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6467 This is made easier because the IR is already in SSA form.
6468 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6469 types are frequently used incorrectly.
6474 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6475 it with the file containing the methods emitted by the JIT and the AOT data
6479 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6480 * - each bblock should end with a branch
6481 * - setting the return value, making cfg->ret non-volatile
6482 * - avoid some transformations in the JIT which make it harder for us to generate
6484 * - use pointer types to help optimizations.