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/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/utils/mono-tls.h>
15 #include <mono/utils/mono-dl.h>
16 #include <mono/utils/mono-time.h>
17 #include <mono/utils/freebsd-dwarf.h>
19 #ifndef __STDC_LIMIT_MACROS
20 #define __STDC_LIMIT_MACROS
22 #ifndef __STDC_CONSTANT_MACROS
23 #define __STDC_CONSTANT_MACROS
26 #include "llvm-c/Core.h"
27 #include "llvm-c/ExecutionEngine.h"
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
36 extern void *memset(void *, int, size_t);
37 void bzero (void *to, size_t count) { memset (to, 0, count); }
41 #if LLVM_API_VERSION < 4
42 #error "The version of the mono llvm repository is too old."
46 * Information associated by mono with LLVM modules.
50 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
51 GHashTable *llvm_types;
53 const char *got_symbol;
54 const char *get_method_symbol;
55 const char *get_unbox_tramp_symbol;
56 GHashTable *plt_entries;
57 GHashTable *plt_entries_ji;
58 GHashTable *method_to_lmethod;
63 GPtrArray *subprogram_mds;
65 LLVMExecutionEngineRef ee;
66 gboolean external_symbols;
71 MonoAssembly *assembly;
73 MonoAotFileInfo aot_info;
74 const char *jit_got_symbol;
75 const char *eh_frame_symbol;
76 LLVMValueRef get_method, get_unbox_tramp;
77 LLVMValueRef code_start, code_end;
78 LLVMValueRef inited_var;
79 int max_inited_idx, max_method_idx;
80 gboolean has_jitted_code;
83 GHashTable *idx_to_lmethod;
84 GHashTable *idx_to_unbox_tramp;
85 LLVMContextRef context;
86 LLVMValueRef sentinel_exception;
90 * Information associated by the backend with mono basic blocks.
93 LLVMBasicBlockRef bblock, end_bblock;
94 LLVMValueRef finally_ind;
95 gboolean added, invoke_target;
97 * If this bblock is the start of a finally clause, this is a list of bblocks it
98 * needs to branch to in ENDFINALLY.
100 GSList *call_handler_return_bbs;
102 * If this bblock is the start of a finally clause, this is the bblock that
103 * CALL_HANDLER needs to branch to.
105 LLVMBasicBlockRef call_handler_target_bb;
106 /* The list of switch statements generated by ENDFINALLY instructions */
107 GSList *endfinally_switch_ins_list;
112 * Structure containing emit state
115 MonoMemPool *mempool;
117 /* Maps method names to the corresponding LLVMValueRef */
118 GHashTable *emitted_method_decls;
121 LLVMValueRef lmethod;
122 MonoLLVMModule *lmodule;
123 LLVMModuleRef module;
125 int sindex, default_index, ex_index;
126 LLVMBuilderRef builder;
127 LLVMValueRef *values, *addresses;
128 MonoType **vreg_cli_types;
130 MonoMethodSignature *sig;
132 GHashTable *region_to_handler;
133 GHashTable *clause_to_handler;
134 LLVMBuilderRef alloca_builder;
135 LLVMValueRef last_alloca;
136 LLVMValueRef rgctx_arg;
137 LLVMValueRef this_arg;
138 LLVMTypeRef *vreg_types;
140 gboolean *unreachable;
143 int this_arg_pindex, rgctx_arg_pindex;
144 LLVMValueRef imt_rgctx_loc;
145 GHashTable *llvm_types;
147 MonoDebugMethodInfo *minfo;
149 /* For every clause, the clauses it is nested in */
152 GHashTable *exc_meta;
153 LLVMBasicBlockRef entry_out_bb;
159 MonoBasicBlock *in_bb;
164 * Instruction metadata
165 * This is the same as ins_info, but LREG != IREG.
173 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
174 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
181 /* keep in sync with the enum in mini.h */
184 #include "mini-ops.h"
189 #if SIZEOF_VOID_P == 4
190 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
192 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
195 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
198 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
200 #define TRACE_FAILURE(msg)
204 #define IS_TARGET_X86 1
206 #define IS_TARGET_X86 0
210 #define IS_TARGET_AMD64 1
212 #define IS_TARGET_AMD64 0
215 #define LLVM_FAILURE(ctx, reason) do { \
216 TRACE_FAILURE (reason); \
217 (ctx)->cfg->exception_message = g_strdup (reason); \
218 (ctx)->cfg->disable_llvm = TRUE; \
222 #define CHECK_FAILURE(ctx) do { \
223 if ((ctx)->cfg->disable_llvm) \
227 static LLVMIntPredicate cond_to_llvm_cond [] = {
240 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
253 static MonoNativeTlsKey current_cfg_tls_id;
255 static MonoLLVMModule aot_module;
256 static int memset_param_count, memcpy_param_count;
257 static const char *memset_func_name;
258 static const char *memcpy_func_name;
260 static void init_jit_module (MonoDomain *domain);
262 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
263 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
264 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
269 * The LLVM type with width == sizeof (gpointer)
274 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
280 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
286 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
292 * Return the size of the LLVM representation of the vtype T.
295 get_vtype_size (MonoType *t)
299 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
301 /* LLVMArgAsIArgs depends on this since it stores whole words */
302 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
309 * simd_class_to_llvm_type:
311 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
314 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
316 if (!strcmp (klass->name, "Vector2d")) {
317 return LLVMVectorType (LLVMDoubleType (), 2);
318 } else if (!strcmp (klass->name, "Vector2l")) {
319 return LLVMVectorType (LLVMInt64Type (), 2);
320 } else if (!strcmp (klass->name, "Vector2ul")) {
321 return LLVMVectorType (LLVMInt64Type (), 2);
322 } else if (!strcmp (klass->name, "Vector4i")) {
323 return LLVMVectorType (LLVMInt32Type (), 4);
324 } else if (!strcmp (klass->name, "Vector4ui")) {
325 return LLVMVectorType (LLVMInt32Type (), 4);
326 } else if (!strcmp (klass->name, "Vector4f")) {
327 return LLVMVectorType (LLVMFloatType (), 4);
328 } else if (!strcmp (klass->name, "Vector8s")) {
329 return LLVMVectorType (LLVMInt16Type (), 8);
330 } else if (!strcmp (klass->name, "Vector8us")) {
331 return LLVMVectorType (LLVMInt16Type (), 8);
332 } else if (!strcmp (klass->name, "Vector16sb")) {
333 return LLVMVectorType (LLVMInt8Type (), 16);
334 } else if (!strcmp (klass->name, "Vector16b")) {
335 return LLVMVectorType (LLVMInt8Type (), 16);
337 printf ("%s\n", klass->name);
343 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
344 static inline G_GNUC_UNUSED LLVMTypeRef
345 type_to_simd_type (int type)
349 return LLVMVectorType (LLVMInt8Type (), 16);
351 return LLVMVectorType (LLVMInt16Type (), 8);
353 return LLVMVectorType (LLVMInt32Type (), 4);
355 return LLVMVectorType (LLVMInt64Type (), 2);
357 return LLVMVectorType (LLVMDoubleType (), 2);
359 return LLVMVectorType (LLVMFloatType (), 4);
361 g_assert_not_reached ();
367 create_llvm_type_for_type (MonoClass *klass)
369 int i, size, nfields, esize;
370 LLVMTypeRef *eltypes;
375 t = &klass->byval_arg;
377 if (mini_type_is_hfa (t, &nfields, &esize)) {
379 * This is needed on arm64 where HFAs are returned in
383 eltypes = g_new (LLVMTypeRef, size);
384 for (i = 0; i < size; ++i)
385 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
387 size = get_vtype_size (t);
389 eltypes = g_new (LLVMTypeRef, size);
390 for (i = 0; i < size; ++i)
391 eltypes [i] = LLVMInt8Type ();
394 name = mono_type_full_name (&klass->byval_arg);
395 ltype = LLVMStructCreateNamed (aot_module.context, name);
396 LLVMStructSetBody (ltype, eltypes, size, FALSE);
406 * Return the LLVM type corresponding to T.
409 type_to_llvm_type (EmitContext *ctx, MonoType *t)
412 return LLVMPointerType (LLVMInt8Type (), 0);
414 t = mini_get_underlying_type (t);
417 return LLVMVoidType ();
419 return LLVMInt8Type ();
421 return LLVMInt16Type ();
423 return LLVMInt32Type ();
425 return LLVMInt8Type ();
427 return LLVMInt16Type ();
429 return LLVMInt32Type ();
430 case MONO_TYPE_BOOLEAN:
431 return LLVMInt8Type ();
434 return LLVMInt64Type ();
436 return LLVMInt16Type ();
438 return LLVMFloatType ();
440 return LLVMDoubleType ();
443 return IntPtrType ();
444 case MONO_TYPE_OBJECT:
445 case MONO_TYPE_CLASS:
446 case MONO_TYPE_ARRAY:
447 case MONO_TYPE_SZARRAY:
448 case MONO_TYPE_STRING:
450 return ObjRefType ();
453 /* Because of generic sharing */
454 return ObjRefType ();
455 case MONO_TYPE_GENERICINST:
456 if (!mono_type_generic_inst_is_valuetype (t))
457 return ObjRefType ();
459 case MONO_TYPE_VALUETYPE:
460 case MONO_TYPE_TYPEDBYREF: {
464 klass = mono_class_from_mono_type (t);
466 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
467 return simd_class_to_llvm_type (ctx, klass);
470 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
472 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
474 ltype = create_llvm_type_for_type (klass);
475 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
481 printf ("X: %d\n", t->type);
482 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
483 ctx->cfg->disable_llvm = TRUE;
491 * Return whenever T is an unsigned int type.
494 type_is_unsigned (EmitContext *ctx, MonoType *t)
511 * type_to_llvm_arg_type:
513 * Same as type_to_llvm_type, but treat i8/i16 as i32.
516 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
518 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
521 * This works on all abis except arm64/ios which passes multiple
522 * arguments in one stack slot.
525 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
527 * LLVM generates code which only sets the lower bits, while JITted
528 * code expects all the bits to be set.
530 ptype = LLVMInt32Type ();
538 * llvm_type_to_stack_type:
540 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
543 static G_GNUC_UNUSED LLVMTypeRef
544 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
548 if (type == LLVMInt8Type ())
549 return LLVMInt32Type ();
550 else if (type == LLVMInt16Type ())
551 return LLVMInt32Type ();
552 else if (!cfg->r4fp && type == LLVMFloatType ())
553 return LLVMDoubleType ();
559 * regtype_to_llvm_type:
561 * Return the LLVM type corresponding to the regtype C used in instruction
565 regtype_to_llvm_type (char c)
569 return LLVMInt32Type ();
571 return LLVMInt64Type ();
573 return LLVMDoubleType ();
582 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
585 op_to_llvm_type (int opcode)
590 return LLVMInt8Type ();
593 return LLVMInt8Type ();
596 return LLVMInt16Type ();
599 return LLVMInt16Type ();
602 return LLVMInt32Type ();
605 return LLVMInt32Type ();
607 return LLVMInt64Type ();
609 return LLVMFloatType ();
611 return LLVMDoubleType ();
613 return LLVMInt64Type ();
615 return LLVMInt32Type ();
617 return LLVMInt64Type ();
622 return LLVMInt8Type ();
627 return LLVMInt16Type ();
630 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
637 return LLVMInt32Type ();
644 return LLVMInt64Type ();
646 printf ("%s\n", mono_inst_name (opcode));
647 g_assert_not_reached ();
652 #define CLAUSE_START(clause) ((clause)->try_offset)
653 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
656 * load_store_to_llvm_type:
658 * Return the size/sign/zero extension corresponding to the load/store opcode
662 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
668 case OP_LOADI1_MEMBASE:
669 case OP_STOREI1_MEMBASE_REG:
670 case OP_STOREI1_MEMBASE_IMM:
671 case OP_ATOMIC_LOAD_I1:
672 case OP_ATOMIC_STORE_I1:
675 return LLVMInt8Type ();
676 case OP_LOADU1_MEMBASE:
678 case OP_ATOMIC_LOAD_U1:
679 case OP_ATOMIC_STORE_U1:
682 return LLVMInt8Type ();
683 case OP_LOADI2_MEMBASE:
684 case OP_STOREI2_MEMBASE_REG:
685 case OP_STOREI2_MEMBASE_IMM:
686 case OP_ATOMIC_LOAD_I2:
687 case OP_ATOMIC_STORE_I2:
690 return LLVMInt16Type ();
691 case OP_LOADU2_MEMBASE:
693 case OP_ATOMIC_LOAD_U2:
694 case OP_ATOMIC_STORE_U2:
697 return LLVMInt16Type ();
698 case OP_LOADI4_MEMBASE:
699 case OP_LOADU4_MEMBASE:
702 case OP_STOREI4_MEMBASE_REG:
703 case OP_STOREI4_MEMBASE_IMM:
704 case OP_ATOMIC_LOAD_I4:
705 case OP_ATOMIC_STORE_I4:
706 case OP_ATOMIC_LOAD_U4:
707 case OP_ATOMIC_STORE_U4:
709 return LLVMInt32Type ();
710 case OP_LOADI8_MEMBASE:
712 case OP_STOREI8_MEMBASE_REG:
713 case OP_STOREI8_MEMBASE_IMM:
714 case OP_ATOMIC_LOAD_I8:
715 case OP_ATOMIC_STORE_I8:
716 case OP_ATOMIC_LOAD_U8:
717 case OP_ATOMIC_STORE_U8:
719 return LLVMInt64Type ();
720 case OP_LOADR4_MEMBASE:
721 case OP_STORER4_MEMBASE_REG:
722 case OP_ATOMIC_LOAD_R4:
723 case OP_ATOMIC_STORE_R4:
725 return LLVMFloatType ();
726 case OP_LOADR8_MEMBASE:
727 case OP_STORER8_MEMBASE_REG:
728 case OP_ATOMIC_LOAD_R8:
729 case OP_ATOMIC_STORE_R8:
731 return LLVMDoubleType ();
732 case OP_LOAD_MEMBASE:
734 case OP_STORE_MEMBASE_REG:
735 case OP_STORE_MEMBASE_IMM:
736 *size = sizeof (gpointer);
737 return IntPtrType ();
739 g_assert_not_reached ();
747 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
750 ovf_op_to_intrins (int opcode)
754 return "llvm.sadd.with.overflow.i32";
756 return "llvm.uadd.with.overflow.i32";
758 return "llvm.ssub.with.overflow.i32";
760 return "llvm.usub.with.overflow.i32";
762 return "llvm.smul.with.overflow.i32";
764 return "llvm.umul.with.overflow.i32";
766 return "llvm.sadd.with.overflow.i64";
768 return "llvm.uadd.with.overflow.i64";
770 return "llvm.ssub.with.overflow.i64";
772 return "llvm.usub.with.overflow.i64";
774 return "llvm.smul.with.overflow.i64";
776 return "llvm.umul.with.overflow.i64";
778 g_assert_not_reached ();
784 simd_op_to_intrins (int opcode)
787 #if defined(TARGET_X86) || defined(TARGET_AMD64)
789 return "llvm.x86.sse2.min.pd";
791 return "llvm.x86.sse.min.ps";
793 return "llvm.x86.sse41.pminud";
795 return "llvm.x86.sse41.pminuw";
797 return "llvm.x86.sse2.pminu.b";
799 return "llvm.x86.sse2.pmins.w";
801 return "llvm.x86.sse2.max.pd";
803 return "llvm.x86.sse.max.ps";
805 return "llvm.x86.sse3.hadd.pd";
807 return "llvm.x86.sse3.hadd.ps";
809 return "llvm.x86.sse3.hsub.pd";
811 return "llvm.x86.sse3.hsub.ps";
813 return "llvm.x86.sse41.pmaxud";
815 return "llvm.x86.sse41.pmaxuw";
817 return "llvm.x86.sse2.pmaxu.b";
819 return "llvm.x86.sse3.addsub.ps";
821 return "llvm.x86.sse3.addsub.pd";
822 case OP_EXTRACT_MASK:
823 return "llvm.x86.sse2.pmovmskb.128";
826 return "llvm.x86.sse2.psrli.w";
829 return "llvm.x86.sse2.psrli.d";
832 return "llvm.x86.sse2.psrli.q";
835 return "llvm.x86.sse2.pslli.w";
838 return "llvm.x86.sse2.pslli.d";
841 return "llvm.x86.sse2.pslli.q";
844 return "llvm.x86.sse2.psrai.w";
847 return "llvm.x86.sse2.psrai.d";
849 return "llvm.x86.sse2.padds.b";
851 return "llvm.x86.sse2.padds.w";
853 return "llvm.x86.sse2.psubs.b";
855 return "llvm.x86.sse2.psubs.w";
856 case OP_PADDB_SAT_UN:
857 return "llvm.x86.sse2.paddus.b";
858 case OP_PADDW_SAT_UN:
859 return "llvm.x86.sse2.paddus.w";
860 case OP_PSUBB_SAT_UN:
861 return "llvm.x86.sse2.psubus.b";
862 case OP_PSUBW_SAT_UN:
863 return "llvm.x86.sse2.psubus.w";
865 return "llvm.x86.sse2.pavg.b";
867 return "llvm.x86.sse2.pavg.w";
869 return "llvm.x86.sse.sqrt.ps";
871 return "llvm.x86.sse2.sqrt.pd";
873 return "llvm.x86.sse.rsqrt.ps";
875 return "llvm.x86.sse.rcp.ps";
877 return "llvm.x86.sse2.cvtdq2pd";
879 return "llvm.x86.sse2.cvtdq2ps";
881 return "llvm.x86.sse2.cvtpd2dq";
883 return "llvm.x86.sse2.cvtps2dq";
885 return "llvm.x86.sse2.cvtpd2ps";
887 return "llvm.x86.sse2.cvtps2pd";
889 return "llvm.x86.sse2.cvttpd2dq";
891 return "llvm.x86.sse2.cvttps2dq";
893 return "llvm.x86.sse.cmp.ps";
895 return "llvm.x86.sse2.cmp.pd";
897 return "llvm.x86.sse2.packsswb.128";
899 return "llvm.x86.sse2.packssdw.128";
901 return "llvm.x86.sse2.packuswb.128";
903 return "llvm.x86.sse41.packusdw";
905 return "llvm.x86.sse2.pmulh.w";
906 case OP_PMULW_HIGH_UN:
907 return "llvm.x86.sse2.pmulhu.w";
910 g_assert_not_reached ();
916 simd_op_to_llvm_type (int opcode)
918 #if defined(TARGET_X86) || defined(TARGET_AMD64)
922 return type_to_simd_type (MONO_TYPE_R8);
925 return type_to_simd_type (MONO_TYPE_I8);
928 return type_to_simd_type (MONO_TYPE_I4);
933 return type_to_simd_type (MONO_TYPE_I2);
937 return type_to_simd_type (MONO_TYPE_I1);
939 return type_to_simd_type (MONO_TYPE_R4);
942 return type_to_simd_type (MONO_TYPE_I4);
946 return type_to_simd_type (MONO_TYPE_R8);
950 return type_to_simd_type (MONO_TYPE_R4);
951 case OP_EXTRACT_MASK:
952 return type_to_simd_type (MONO_TYPE_I1);
958 return type_to_simd_type (MONO_TYPE_R4);
961 return type_to_simd_type (MONO_TYPE_R8);
963 g_assert_not_reached ();
974 * Return the LLVM basic block corresponding to BB.
976 static LLVMBasicBlockRef
977 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
979 char bb_name_buf [128];
982 if (ctx->bblocks [bb->block_num].bblock == NULL) {
983 if (bb->flags & BB_EXCEPTION_HANDLER) {
984 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
985 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
986 bb_name = bb_name_buf;
987 } else if (bb->block_num < 256) {
988 if (!ctx->lmodule->bb_names) {
989 ctx->lmodule->bb_names_len = 256;
990 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
992 if (!ctx->lmodule->bb_names [bb->block_num]) {
995 n = g_strdup_printf ("BB%d", bb->block_num);
996 mono_memory_barrier ();
997 ctx->lmodule->bb_names [bb->block_num] = n;
999 bb_name = ctx->lmodule->bb_names [bb->block_num];
1001 sprintf (bb_name_buf, "BB%d", bb->block_num);
1002 bb_name = bb_name_buf;
1005 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1006 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1009 return ctx->bblocks [bb->block_num].bblock;
1015 * Return the last LLVM bblock corresponding to BB.
1016 * This might not be equal to the bb returned by get_bb () since we need to generate
1017 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1019 static LLVMBasicBlockRef
1020 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1023 return ctx->bblocks [bb->block_num].end_bblock;
1026 static LLVMBasicBlockRef
1027 gen_bb (EmitContext *ctx, const char *prefix)
1031 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1032 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1038 * Return the target of the patch identified by TYPE and TARGET.
1041 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1045 memset (&ji, 0, sizeof (ji));
1047 ji.data.target = target;
1049 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1055 * Emit code to convert the LLVM value V to DTYPE.
1058 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1060 LLVMTypeRef stype = LLVMTypeOf (v);
1062 if (stype != dtype) {
1063 gboolean ext = FALSE;
1066 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1068 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1070 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1074 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1076 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1077 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1080 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1081 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1082 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1083 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1084 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1085 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1086 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1087 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1089 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1090 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1091 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1092 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1093 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1094 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1096 if (mono_arch_is_soft_float ()) {
1097 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1098 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1099 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1100 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1103 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1104 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1107 LLVMDumpValue (LLVMConstNull (dtype));
1108 g_assert_not_reached ();
1116 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1118 return convert_full (ctx, v, dtype, FALSE);
1122 * emit_volatile_load:
1124 * If vreg is volatile, emit a load from its address.
1127 emit_volatile_load (EmitContext *ctx, int vreg)
1131 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1132 t = ctx->vreg_cli_types [vreg];
1133 if (t && !t->byref) {
1135 * Might have to zero extend since llvm doesn't have
1138 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1139 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1140 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1141 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1142 else if (t->type == MONO_TYPE_U8)
1143 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1150 * emit_volatile_store:
1152 * If VREG is volatile, emit a store from its value to its address.
1155 emit_volatile_store (EmitContext *ctx, int vreg)
1157 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1159 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1160 g_assert (ctx->addresses [vreg]);
1161 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1167 * Maps parameter indexes in the original signature to parameter indexes
1168 * in the LLVM signature.
1171 /* The indexes of various special arguments in the LLVM signature */
1172 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1176 * sig_to_llvm_sig_full:
1178 * Return the LLVM signature corresponding to the mono signature SIG using the
1179 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1182 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1185 LLVMTypeRef ret_type;
1186 LLVMTypeRef *param_types = NULL;
1188 int i, j, pindex, vret_arg_pindex = 0;
1190 gboolean vretaddr = FALSE;
1194 memset (sinfo, 0, sizeof (LLVMSigInfo));
1196 rtype = mini_get_underlying_type (sig->ret);
1197 ret_type = type_to_llvm_type (ctx, rtype);
1198 CHECK_FAILURE (ctx);
1201 switch (cinfo->ret.storage) {
1202 case LLVMArgVtypeInReg:
1203 /* LLVM models this by returning an aggregate value */
1204 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1205 LLVMTypeRef members [2];
1207 members [0] = IntPtrType ();
1208 ret_type = LLVMStructType (members, 1, FALSE);
1209 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1211 ret_type = LLVMVoidType ();
1213 g_assert_not_reached ();
1216 case LLVMArgVtypeByVal:
1217 /* Vtype returned normally by val */
1219 case LLVMArgVtypeAsScalar:
1220 /* LLVM models this by returning an int */
1221 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1222 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1224 case LLVMArgFpStruct: {
1225 /* Vtype returned as a fp struct */
1226 LLVMTypeRef members [16];
1228 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1229 for (i = 0; i < cinfo->ret.nslots; ++i)
1230 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1231 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1234 case LLVMArgVtypeByRef:
1235 /* Vtype returned using a hidden argument */
1236 ret_type = LLVMVoidType ();
1239 if (mini_type_is_vtype (rtype)) {
1240 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1242 ret_type = LLVMVoidType ();
1248 pindexes = g_new0 (int, sig->param_count);
1249 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1251 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef) {
1253 * Has to be the first argument because of the sret argument attribute
1254 * FIXME: This might conflict with passing 'this' as the first argument, but
1255 * this is only used on arm64 which has a dedicated struct return register.
1258 sinfo->vret_arg_pindex = pindex;
1259 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1260 CHECK_FAILURE (ctx);
1261 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1264 if (!ctx->llvm_only && cinfo && cinfo->rgctx_arg) {
1266 sinfo->rgctx_arg_pindex = pindex;
1267 param_types [pindex] = ctx->lmodule->ptr_type;
1270 if (cinfo && cinfo->imt_arg) {
1272 sinfo->imt_arg_pindex = pindex;
1273 param_types [pindex] = ctx->lmodule->ptr_type;
1277 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1278 vret_arg_pindex = pindex;
1279 if (cinfo->vret_arg_index == 1) {
1280 /* Add the slots consumed by the first argument */
1281 LLVMArgInfo *ainfo = &cinfo->args [0];
1282 switch (ainfo->storage) {
1283 case LLVMArgVtypeInReg:
1284 for (j = 0; j < 2; ++j) {
1285 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1295 sinfo->vret_arg_pindex = vret_arg_pindex;
1298 if (vretaddr && vret_arg_pindex == pindex)
1299 param_types [pindex ++] = IntPtrType ();
1302 sinfo->this_arg_pindex = pindex;
1303 param_types [pindex ++] = ThisType ();
1305 if (vretaddr && vret_arg_pindex == pindex)
1306 param_types [pindex ++] = IntPtrType ();
1307 for (i = 0; i < sig->param_count; ++i) {
1308 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1310 if (vretaddr && vret_arg_pindex == pindex)
1311 param_types [pindex ++] = IntPtrType ();
1312 pindexes [i] = pindex;
1315 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1319 switch (ainfo->storage) {
1320 case LLVMArgVtypeInReg:
1321 for (j = 0; j < 2; ++j) {
1322 switch (ainfo->pair_storage [j]) {
1324 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1329 g_assert_not_reached ();
1333 case LLVMArgVtypeByVal:
1334 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1335 CHECK_FAILURE (ctx);
1336 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1339 case LLVMArgAsIArgs:
1340 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1343 case LLVMArgVtypeByRef:
1344 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1345 CHECK_FAILURE (ctx);
1346 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1349 case LLVMArgAsFpArgs: {
1352 for (j = 0; j < ainfo->nslots; ++j)
1353 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1354 pindex += ainfo->nslots;
1357 case LLVMArgVtypeAsScalar:
1358 g_assert_not_reached ();
1361 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 if (ctx->llvm_only && cinfo && cinfo->rgctx_arg) {
1368 /* Pass the rgctx as the last argument */
1370 sinfo->rgctx_arg_pindex = pindex;
1371 param_types [pindex] = ctx->lmodule->ptr_type;
1375 CHECK_FAILURE (ctx);
1377 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1378 g_free (param_types);
1381 sinfo->pindexes = pindexes;
1389 g_free (param_types);
1395 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1397 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1401 * LLVMFunctionType1:
1403 * Create an LLVM function type from the arguments.
1405 static G_GNUC_UNUSED LLVMTypeRef
1406 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1409 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1413 * LLVMFunctionType1:
1415 * Create an LLVM function type from the arguments.
1417 static G_GNUC_UNUSED LLVMTypeRef
1418 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1419 LLVMTypeRef ParamType1,
1422 LLVMTypeRef param_types [1];
1424 param_types [0] = ParamType1;
1426 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1430 * LLVMFunctionType2:
1432 * Create an LLVM function type from the arguments.
1434 static G_GNUC_UNUSED LLVMTypeRef
1435 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1436 LLVMTypeRef ParamType1,
1437 LLVMTypeRef ParamType2,
1440 LLVMTypeRef param_types [2];
1442 param_types [0] = ParamType1;
1443 param_types [1] = ParamType2;
1445 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1449 * LLVMFunctionType3:
1451 * Create an LLVM function type from the arguments.
1453 static G_GNUC_UNUSED LLVMTypeRef
1454 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1455 LLVMTypeRef ParamType1,
1456 LLVMTypeRef ParamType2,
1457 LLVMTypeRef ParamType3,
1460 LLVMTypeRef param_types [3];
1462 param_types [0] = ParamType1;
1463 param_types [1] = ParamType2;
1464 param_types [2] = ParamType3;
1466 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1472 * Create an LLVM builder and remember it so it can be freed later.
1474 static LLVMBuilderRef
1475 create_builder (EmitContext *ctx)
1477 LLVMBuilderRef builder = LLVMCreateBuilder ();
1479 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1485 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1489 LLVMValueRef indexes [2];
1491 LLVMValueRef got_entry_addr, load;
1492 LLVMBuilderRef builder = ctx->builder;
1497 ji = g_new0 (MonoJumpInfo, 1);
1499 ji->data.target = data;
1501 ji = mono_aot_patch_info_dup (ji);
1503 ji->next = cfg->patch_info;
1504 cfg->patch_info = ji;
1506 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1507 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
1509 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1510 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1511 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
1514 case MONO_PATCH_INFO_INTERNAL_METHOD:
1515 name = g_strdup_printf ("jit_icall_%s", data);
1521 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1523 //set_invariant_load_flag (load);
1529 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1531 if (ctx->llvm_only) {
1535 * Calls are made through the GOT.
1537 load = get_aotconst (ctx, type, data);
1539 return convert (ctx, load, LLVMPointerType (llvm_sig, 0));
1541 char *callee_name = mono_aot_get_plt_symbol (type, data);
1542 LLVMValueRef callee;
1543 MonoJumpInfo *ji = NULL;
1548 if (ctx->cfg->compile_aot)
1549 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1550 mono_add_patch_info (ctx->cfg, 0, type, data);
1553 callee = (LLVMValueRef)g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1555 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1557 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1559 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1562 if (ctx->cfg->compile_aot) {
1563 ji = g_new0 (MonoJumpInfo, 1);
1565 ji->data.target = data;
1567 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1575 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1577 MonoMethodHeader *header = cfg->header;
1578 MonoExceptionClause *clause;
1582 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1583 return (bb->region >> 8) - 1;
1586 for (i = 0; i < header->num_clauses; ++i) {
1587 clause = &header->clauses [i];
1589 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1596 static MonoExceptionClause *
1597 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1599 // Since they're sorted by nesting we just need
1600 // the first one that the bb is a member of
1601 MonoExceptionClause *last = NULL;
1603 for (int i = 0; i < cfg->header->num_clauses; i++) {
1604 MonoExceptionClause *curr = &cfg->header->clauses [i];
1606 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1609 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1610 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1624 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1626 LLVMValueRef md_arg;
1629 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1630 md_arg = LLVMMDString ("mono", 4);
1631 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1635 set_invariant_load_flag (LLVMValueRef v)
1637 LLVMValueRef md_arg;
1639 const char *flag_name;
1641 // FIXME: Cache this
1642 flag_name = "invariant.load";
1643 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1644 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1645 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1651 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1655 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1657 MonoCompile *cfg = ctx->cfg;
1658 LLVMValueRef lcall = NULL;
1659 LLVMBuilderRef builder = *builder_ref;
1660 MonoExceptionClause *clause;
1662 if (ctx->llvm_only) {
1663 clause = get_most_deep_clause (cfg, ctx, bb);
1666 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1669 * Have to use an invoke instead of a call, branching to the
1670 * handler bblock of the clause containing this bblock.
1672 intptr_t key = CLAUSE_END(clause);
1674 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1676 // FIXME: Find the one that has the lowest end bound for the right start address
1677 // FIXME: Finally + nesting
1680 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1683 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1685 builder = ctx->builder = create_builder (ctx);
1686 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1688 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1692 int clause_index = get_handler_clause (cfg, bb);
1694 if (clause_index != -1) {
1695 MonoMethodHeader *header = cfg->header;
1696 MonoExceptionClause *ec = &header->clauses [clause_index];
1697 MonoBasicBlock *tblock;
1698 LLVMBasicBlockRef ex_bb, noex_bb;
1701 * Have to use an invoke instead of a call, branching to the
1702 * handler bblock of the clause containing this bblock.
1705 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1707 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1710 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1712 ex_bb = get_bb (ctx, tblock);
1714 noex_bb = gen_bb (ctx, "NOEX_BB");
1717 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1719 builder = ctx->builder = create_builder (ctx);
1720 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1722 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1727 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1728 ctx->builder = builder;
1732 *builder_ref = ctx->builder;
1738 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1740 const char *intrins_name;
1741 LLVMValueRef args [16], res;
1742 LLVMTypeRef addr_type;
1744 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1745 LLVMAtomicOrdering ordering;
1748 case LLVM_BARRIER_NONE:
1749 ordering = LLVMAtomicOrderingNotAtomic;
1751 case LLVM_BARRIER_ACQ:
1752 ordering = LLVMAtomicOrderingAcquire;
1754 case LLVM_BARRIER_SEQ:
1755 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1758 g_assert_not_reached ();
1763 * We handle loads which can fault by calling a mono specific intrinsic
1764 * using an invoke, so they are handled properly inside try blocks.
1765 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1766 * are marked with IntrReadArgMem.
1770 intrins_name = "llvm.mono.load.i8.p0i8";
1773 intrins_name = "llvm.mono.load.i16.p0i16";
1776 intrins_name = "llvm.mono.load.i32.p0i32";
1779 intrins_name = "llvm.mono.load.i64.p0i64";
1782 g_assert_not_reached ();
1785 addr_type = LLVMTypeOf (addr);
1786 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1787 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1790 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1791 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1792 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1793 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1795 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1796 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1797 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1798 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1805 * We emit volatile loads for loads which can fault, because otherwise
1806 * LLVM will generate invalid code when encountering a load from a
1809 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1811 /* Mark it with a custom metadata */
1814 set_metadata_flag (res, "mono.faulting.load");
1822 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1824 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1828 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1830 const char *intrins_name;
1831 LLVMValueRef args [16];
1833 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1834 LLVMAtomicOrdering ordering;
1837 case LLVM_BARRIER_NONE:
1838 ordering = LLVMAtomicOrderingNotAtomic;
1840 case LLVM_BARRIER_REL:
1841 ordering = LLVMAtomicOrderingRelease;
1843 case LLVM_BARRIER_SEQ:
1844 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1847 g_assert_not_reached ();
1853 intrins_name = "llvm.mono.store.i8.p0i8";
1856 intrins_name = "llvm.mono.store.i16.p0i16";
1859 intrins_name = "llvm.mono.store.i32.p0i32";
1862 intrins_name = "llvm.mono.store.i64.p0i64";
1865 g_assert_not_reached ();
1868 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1869 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1870 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1875 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1876 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1877 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1878 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1880 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1885 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1887 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1891 * emit_cond_system_exception:
1893 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1894 * Might set the ctx exception.
1897 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1899 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
1900 LLVMBuilderRef builder;
1901 MonoClass *exc_class;
1902 LLVMValueRef args [2];
1903 LLVMValueRef callee;
1905 ex_bb = gen_bb (ctx, "EX_BB");
1907 ex2_bb = gen_bb (ctx, "EX2_BB");
1908 noex_bb = gen_bb (ctx, "NOEX_BB");
1910 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1912 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1913 g_assert (exc_class);
1915 /* Emit exception throwing code */
1916 ctx->builder = builder = create_builder (ctx);
1917 LLVMPositionBuilderAtEnd (builder, ex_bb);
1919 if (ctx->cfg->llvm_only) {
1920 static LLVMTypeRef sig;
1923 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
1924 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
1926 LLVMBuildBr (builder, ex2_bb);
1928 ctx->builder = builder = create_builder (ctx);
1929 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
1931 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1932 emit_call (ctx, bb, &builder, callee, args, 1);
1933 LLVMBuildUnreachable (builder);
1935 ctx->builder = builder = create_builder (ctx);
1936 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1938 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1944 callee = ctx->lmodule->throw_corlib_exception;
1947 const char *icall_name;
1949 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
1950 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1952 if (ctx->cfg->compile_aot) {
1953 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1955 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig);
1958 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1959 * - On x86, LLVM generated code doesn't push the arguments
1960 * - The trampoline takes the throw address as an arguments, not a pc offset.
1962 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1964 mono_memory_barrier ();
1965 ctx->lmodule->throw_corlib_exception = callee;
1969 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1970 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1972 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1975 * The LLVM mono branch contains changes so a block address can be passed as an
1976 * argument to a call.
1978 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1979 emit_call (ctx, bb, &builder, callee, args, 2);
1981 LLVMBuildUnreachable (builder);
1983 ctx->builder = builder = create_builder (ctx);
1984 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1986 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1993 * emit_args_to_vtype:
1995 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1998 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2000 int j, size, nslots;
2002 size = get_vtype_size (t);
2004 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2005 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2008 if (ainfo->storage == LLVMArgAsFpArgs)
2009 nslots = ainfo->nslots;
2013 for (j = 0; j < nslots; ++j) {
2014 LLVMValueRef index [2], addr, daddr;
2015 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2016 LLVMTypeRef part_type;
2018 if (ainfo->pair_storage [j] == LLVMArgNone)
2021 switch (ainfo->pair_storage [j]) {
2022 case LLVMArgInIReg: {
2023 part_type = LLVMIntType (part_size * 8);
2024 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2025 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2026 addr = LLVMBuildGEP (builder, address, index, 1, "");
2028 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2029 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2030 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2032 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2035 case LLVMArgInFPReg: {
2036 LLVMTypeRef arg_type;
2038 if (ainfo->esize == 8)
2039 arg_type = LLVMDoubleType ();
2041 arg_type = LLVMFloatType ();
2043 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2044 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2045 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2046 LLVMBuildStore (builder, args [j], addr);
2052 g_assert_not_reached ();
2055 size -= sizeof (gpointer);
2060 * emit_vtype_to_args:
2062 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2063 * into ARGS, and the number of arguments into NARGS.
2066 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2069 int j, size, nslots;
2070 LLVMTypeRef arg_type;
2072 size = get_vtype_size (t);
2074 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2075 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2077 if (ainfo->storage == LLVMArgAsFpArgs)
2078 nslots = ainfo->nslots;
2081 for (j = 0; j < nslots; ++j) {
2082 LLVMValueRef index [2], addr, daddr;
2083 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2085 if (ainfo->pair_storage [j] == LLVMArgNone)
2088 switch (ainfo->pair_storage [j]) {
2090 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2091 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2092 addr = LLVMBuildGEP (builder, address, index, 1, "");
2094 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2095 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2096 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2098 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2100 case LLVMArgInFPReg:
2101 if (ainfo->esize == 8)
2102 arg_type = LLVMDoubleType ();
2104 arg_type = LLVMFloatType ();
2105 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2106 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2107 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2108 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2113 g_assert_not_reached ();
2115 size -= sizeof (gpointer);
2122 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2125 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2126 * get executed every time control reaches them.
2128 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2130 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
2131 return ctx->last_alloca;
2135 build_alloca (EmitContext *ctx, MonoType *t)
2137 MonoClass *k = mono_class_from_mono_type (t);
2140 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2143 align = mono_class_min_align (k);
2145 /* Sometimes align is not a power of 2 */
2146 while (mono_is_power_of_two (align) == -1)
2149 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2153 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2156 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
2159 lmodule->used = g_ptr_array_sized_new (16);
2160 g_ptr_array_add (lmodule->used, global);
2164 emit_llvm_used (MonoLLVMModule *lmodule)
2166 LLVMModuleRef module = lmodule->module;
2167 LLVMTypeRef used_type;
2168 LLVMValueRef used, *used_elem;
2174 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
2175 used = LLVMAddGlobal (module, used_type, "llvm.used");
2176 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
2177 for (i = 0; i < lmodule->used->len; ++i)
2178 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2179 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
2180 LLVMSetLinkage (used, LLVMAppendingLinkage);
2181 LLVMSetSection (used, "llvm.metadata");
2187 * Emit a function mapping method indexes to their code
2190 emit_get_method (MonoLLVMModule *lmodule)
2192 LLVMModuleRef module = lmodule->module;
2193 LLVMValueRef func, switch_ins, m;
2194 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2195 LLVMBasicBlockRef *bbs;
2197 LLVMBuilderRef builder;
2202 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2203 * but generating code seems safer.
2205 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2206 func = LLVMAddFunction (module, lmodule->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2207 LLVMSetLinkage (func, LLVMExternalLinkage);
2208 LLVMSetVisibility (func, LLVMHiddenVisibility);
2209 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2210 lmodule->get_method = func;
2212 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2215 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2216 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2217 * then we will have to find another solution.
2220 name = g_strdup_printf ("BB_CODE_START");
2221 code_start_bb = LLVMAppendBasicBlock (func, name);
2223 builder = LLVMCreateBuilder ();
2224 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2225 LLVMBuildRet (builder, LLVMBuildBitCast (builder, lmodule->code_start, rtype, ""));
2227 name = g_strdup_printf ("BB_CODE_END");
2228 code_end_bb = LLVMAppendBasicBlock (func, name);
2230 builder = LLVMCreateBuilder ();
2231 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2232 LLVMBuildRet (builder, LLVMBuildBitCast (builder, lmodule->code_end, rtype, ""));
2234 bbs = g_new0 (LLVMBasicBlockRef, lmodule->max_method_idx + 1);
2235 for (i = 0; i < lmodule->max_method_idx + 1; ++i) {
2236 name = g_strdup_printf ("BB_%d", i);
2237 bb = LLVMAppendBasicBlock (func, name);
2241 builder = LLVMCreateBuilder ();
2242 LLVMPositionBuilderAtEnd (builder, bb);
2244 m = (LLVMValueRef)g_hash_table_lookup (lmodule->idx_to_lmethod, GINT_TO_POINTER (i));
2246 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2248 LLVMBuildRet (builder, LLVMConstNull (rtype));
2251 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2252 builder = LLVMCreateBuilder ();
2253 LLVMPositionBuilderAtEnd (builder, fail_bb);
2254 LLVMBuildRet (builder, LLVMConstNull (rtype));
2256 builder = LLVMCreateBuilder ();
2257 LLVMPositionBuilderAtEnd (builder, entry_bb);
2259 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2260 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2261 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2262 for (i = 0; i < lmodule->max_method_idx + 1; ++i) {
2263 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2266 mark_as_used (lmodule, func);
2270 * emit_get_unbox_tramp:
2272 * Emit a function mapping method indexes to their unbox trampoline
2275 emit_get_unbox_tramp (MonoLLVMModule *lmodule)
2277 LLVMModuleRef module = lmodule->module;
2278 LLVMValueRef func, switch_ins, m;
2279 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2280 LLVMBasicBlockRef *bbs;
2282 LLVMBuilderRef builder;
2286 /* Similar to emit_get_method () */
2288 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2289 func = LLVMAddFunction (module, lmodule->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2290 LLVMSetLinkage (func, LLVMExternalLinkage);
2291 LLVMSetVisibility (func, LLVMHiddenVisibility);
2292 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2293 lmodule->get_unbox_tramp = func;
2295 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2297 bbs = g_new0 (LLVMBasicBlockRef, lmodule->max_method_idx + 1);
2298 for (i = 0; i < lmodule->max_method_idx + 1; ++i) {
2299 m = (LLVMValueRef)g_hash_table_lookup (lmodule->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2303 name = g_strdup_printf ("BB_%d", i);
2304 bb = LLVMAppendBasicBlock (func, name);
2308 builder = LLVMCreateBuilder ();
2309 LLVMPositionBuilderAtEnd (builder, bb);
2311 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2314 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2315 builder = LLVMCreateBuilder ();
2316 LLVMPositionBuilderAtEnd (builder, fail_bb);
2317 LLVMBuildRet (builder, LLVMConstNull (rtype));
2319 builder = LLVMCreateBuilder ();
2320 LLVMPositionBuilderAtEnd (builder, entry_bb);
2322 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2323 for (i = 0; i < lmodule->max_method_idx + 1; ++i) {
2324 m = (LLVMValueRef)g_hash_table_lookup (lmodule->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2328 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2331 mark_as_used (lmodule, func);
2334 /* Add a function to mark the beginning of LLVM code */
2336 emit_llvm_code_start (MonoLLVMModule *lmodule)
2338 LLVMModuleRef module = lmodule->module;
2340 LLVMBasicBlockRef entry_bb;
2341 LLVMBuilderRef builder;
2343 func = LLVMAddFunction (module, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2344 LLVMSetLinkage (func, LLVMInternalLinkage);
2345 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2346 lmodule->code_start = func;
2347 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2348 builder = LLVMCreateBuilder ();
2349 LLVMPositionBuilderAtEnd (builder, entry_bb);
2350 LLVMBuildRetVoid (builder);
2354 emit_llvm_code_end (MonoLLVMModule *lmodule)
2356 LLVMModuleRef module = lmodule->module;
2358 LLVMBasicBlockRef entry_bb;
2359 LLVMBuilderRef builder;
2361 func = LLVMAddFunction (module, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2362 LLVMSetLinkage (func, LLVMInternalLinkage);
2363 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2364 lmodule->code_end = func;
2365 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2366 builder = LLVMCreateBuilder ();
2367 LLVMPositionBuilderAtEnd (builder, entry_bb);
2368 LLVMBuildRetVoid (builder);
2372 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2374 gboolean need_div_check = FALSE;
2376 #ifdef MONO_ARCH_NEED_DIV_CHECK
2377 need_div_check = TRUE;
2380 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2381 need_div_check = TRUE;
2383 if (!need_div_check)
2386 switch (ins->opcode) {
2399 case OP_IDIV_UN_IMM:
2400 case OP_LDIV_UN_IMM:
2401 case OP_IREM_UN_IMM:
2402 case OP_LREM_UN_IMM: {
2404 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2405 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2407 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2408 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2409 CHECK_FAILURE (ctx);
2410 builder = ctx->builder;
2412 /* b == -1 && a == 0x80000000 */
2414 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2415 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2416 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2418 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2419 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2420 CHECK_FAILURE (ctx);
2421 builder = ctx->builder;
2436 * Emit code to initialize the GOT slots used by the method.
2439 emit_init_method (EmitContext *ctx)
2441 LLVMValueRef indexes [16], args [16], callee;
2442 LLVMValueRef inited_var, cmp;
2443 LLVMBasicBlockRef inited_bb, notinited_bb;
2444 LLVMBuilderRef builder = ctx->builder;
2446 MonoCompile *cfg = ctx->cfg;
2449 // FIXME: The call is not a trampoline, so it clobbers argument registers
2451 // FIXME: Do this only if the method has got slots in the end
2452 // FIXME: Add an aot option for this
2455 ctx->lmodule->max_inited_idx = MAX (ctx->lmodule->max_inited_idx, cfg->method_index);
2456 ctx->lmodule->max_method_idx = MAX (ctx->lmodule->max_method_idx, cfg->method_index);
2458 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2459 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2460 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->lmodule->inited_var, indexes, 2, ""), "");
2462 args [0] = inited_var;
2463 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2464 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->module, "llvm.expect.i8"), args, 2, "");
2466 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2468 inited_bb = gen_bb (ctx, "INITED_BB");
2469 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2471 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2473 builder = ctx->builder = create_builder (ctx);
2474 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2476 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_MODULE, NULL), IntPtrType ());
2477 args [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2480 if (ctx->rgctx_arg) {
2481 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2482 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_aot_init_gshared_method_rgctx");
2483 args [2] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2484 LLVMBuildCall (builder, callee, args, 3, "");
2485 } else if (cfg->gshared) {
2486 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2487 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_aot_init_gshared_method_this");
2488 args [2] = convert (ctx, ctx->this_arg, ObjRefType ());
2489 LLVMBuildCall (builder, callee, args, 3, "");
2491 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2492 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_aot_init_llvm_method");
2493 LLVMBuildCall (builder, callee, args, 2, "");
2496 // Set the inited flag
2497 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2498 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2499 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, ctx->lmodule->inited_var, indexes, 2, ""));
2501 LLVMBuildBr (builder, inited_bb);
2502 ctx->entry_out_bb = inited_bb;
2504 builder = ctx->builder = create_builder (ctx);
2505 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2509 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2512 * Emit unbox trampoline using a tail call
2514 LLVMValueRef tramp, call, *args;
2515 LLVMBuilderRef builder;
2516 LLVMBasicBlockRef lbb;
2520 tramp_name = g_strdup_printf ("ut_%s", method_name);
2521 tramp = LLVMAddFunction (ctx->lmodule->module, tramp_name, method_type);
2522 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2523 LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2524 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2525 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2527 lbb = LLVMAppendBasicBlock (tramp, "");
2528 builder = LLVMCreateBuilder ();
2529 LLVMPositionBuilderAtEnd (builder, lbb);
2531 nargs = LLVMCountParamTypes (method_type);
2532 args = g_new0 (LLVMValueRef, nargs);
2533 for (i = 0; i < nargs; ++i) {
2534 args [i] = LLVMGetParam (tramp, i);
2535 if (i == ctx->this_arg_pindex) {
2536 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2538 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2539 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2540 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2543 call = LLVMBuildCall (builder, method, args, nargs, "");
2544 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2545 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2546 mono_llvm_set_must_tail (call);
2547 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2548 LLVMBuildRetVoid (builder);
2550 LLVMBuildRet (builder, call);
2552 g_hash_table_insert (ctx->lmodule->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2558 * Emit code to load/convert arguments.
2561 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2564 MonoCompile *cfg = ctx->cfg;
2565 MonoMethodSignature *sig = ctx->sig;
2566 LLVMCallInfo *linfo = ctx->linfo;
2569 LLVMBuilderRef old_builder = ctx->builder;
2570 ctx->builder = builder;
2572 ctx->alloca_builder = create_builder (ctx);
2575 * Handle indirect/volatile variables by allocating memory for them
2576 * using 'alloca', and storing their address in a temporary.
2578 for (i = 0; i < cfg->num_varinfo; ++i) {
2579 MonoInst *var = cfg->varinfo [i];
2582 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (var->inst_vtype)) {
2583 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2584 CHECK_FAILURE (ctx);
2585 /* Could be already created by an OP_VPHI */
2586 if (!ctx->addresses [var->dreg])
2587 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2588 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2592 for (i = 0; i < sig->param_count; ++i) {
2593 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2594 int reg = cfg->args [i + sig->hasthis]->dreg;
2596 switch (ainfo->storage) {
2597 case LLVMArgVtypeInReg:
2598 case LLVMArgAsFpArgs: {
2599 LLVMValueRef args [8];
2602 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2603 memset (args, 0, sizeof (args));
2604 pindex = ctx->pindexes [i];
2605 if (ainfo->storage == LLVMArgVtypeInReg) {
2606 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2607 if (ainfo->pair_storage [1] != LLVMArgNone)
2608 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2610 g_assert (ainfo->nslots <= 8);
2611 for (j = 0; j < ainfo->nslots; ++j)
2612 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2614 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2616 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2618 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2619 /* Treat these as normal values */
2620 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2624 case LLVMArgVtypeByVal: {
2625 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2627 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2628 /* Treat these as normal values */
2629 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2633 case LLVMArgVtypeByRef: {
2634 /* The argument is passed by ref */
2635 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2638 case LLVMArgAsIArgs: {
2639 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2641 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2643 /* The argument is received as an array of ints, store it into the real argument */
2644 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2647 case LLVMArgVtypeAsScalar:
2648 g_assert_not_reached ();
2651 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]));
2657 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2659 emit_volatile_store (ctx, cfg->args [0]->dreg);
2660 for (i = 0; i < sig->param_count; ++i)
2661 if (!mini_type_is_vtype (sig->params [i]))
2662 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2664 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2665 LLVMValueRef this_alloc;
2668 * The exception handling code needs the location where the this argument was
2669 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2670 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2671 * location into the LSDA.
2673 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2674 /* This volatile store will keep the alloca alive */
2675 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2677 set_metadata_flag (this_alloc, "mono.this");
2680 if (cfg->rgctx_var) {
2681 LLVMValueRef rgctx_alloc, store;
2684 * We handle the rgctx arg similarly to the this pointer.
2686 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2687 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2688 /* This volatile store will keep the alloca alive */
2689 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2691 set_metadata_flag (rgctx_alloc, "mono.this");
2694 /* Initialize the method if needed */
2695 if (cfg->compile_aot && ctx->llvm_only) {
2696 emit_init_method (ctx);
2697 builder = ctx->builder;
2700 /* Compute nesting between clauses */
2701 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2702 for (i = 0; i < cfg->header->num_clauses; ++i) {
2703 for (j = 0; j < cfg->header->num_clauses; ++j) {
2704 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2705 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2707 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2708 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2713 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2714 * it needs to continue normally, or return back to the exception handling system.
2716 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2720 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2723 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2724 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2725 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2727 if (bb->in_scount == 0) {
2730 sprintf (name, "finally_ind_bb%d", bb->block_num);
2731 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2732 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2734 ctx->bblocks [bb->block_num].finally_ind = val;
2736 /* Create a variable to hold the exception var */
2738 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2742 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2743 * LLVM bblock containing a landing pad causes problems for the
2744 * LLVM optimizer passes.
2746 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
2747 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2754 ctx->builder = old_builder;
2758 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2760 MonoCompile *cfg = ctx->cfg;
2761 LLVMModuleRef module = ctx->module;
2762 LLVMValueRef *values = ctx->values;
2763 LLVMValueRef *addresses = ctx->addresses;
2764 MonoCallInst *call = (MonoCallInst*)ins;
2765 MonoMethodSignature *sig = call->signature;
2766 LLVMValueRef callee = NULL, lcall;
2768 LLVMCallInfo *cinfo;
2772 LLVMTypeRef llvm_sig;
2774 gboolean is_virtual, calli;
2775 LLVMBuilderRef builder = *builder_ref;
2778 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2779 LLVM_FAILURE (ctx, "non-default callconv");
2781 cinfo = call->cinfo;
2782 if (call->rgctx_arg_reg)
2783 cinfo->rgctx_arg = TRUE;
2784 if (call->imt_arg_reg)
2785 cinfo->imt_arg = TRUE;
2787 vretaddr = cinfo && (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef);
2789 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2790 CHECK_FAILURE (ctx);
2792 is_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);
2793 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);
2795 /* FIXME: Avoid creating duplicate methods */
2797 if (ins->flags & MONO_INST_HAS_METHOD) {
2801 if (cfg->compile_aot) {
2802 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2804 LLVM_FAILURE (ctx, "can't encode patch");
2806 callee = LLVMAddFunction (module, "", llvm_sig);
2809 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2811 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2815 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2816 /* LLVM miscompiles async methods */
2817 LLVM_FAILURE (ctx, "#13734");
2820 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2826 memset (&ji, 0, sizeof (ji));
2827 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2828 ji.data.target = info->name;
2830 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2832 if (cfg->compile_aot) {
2833 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2835 LLVM_FAILURE (ctx, "can't encode patch");
2837 callee = LLVMAddFunction (module, "", llvm_sig);
2838 target = (gpointer)mono_icall_get_wrapper (info);
2839 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2842 if (cfg->compile_aot) {
2844 if (cfg->abs_patches) {
2845 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
2847 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2849 LLVM_FAILURE (ctx, "can't encode patch");
2853 LLVM_FAILURE (ctx, "aot");
2855 callee = LLVMAddFunction (module, "", llvm_sig);
2857 if (cfg->abs_patches) {
2858 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
2861 * FIXME: Some trampolines might have
2862 * their own calling convention on some platforms.
2864 #ifndef TARGET_AMD64
2865 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2866 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2867 LLVM_FAILURE (ctx, "trampoline with own cconv");
2869 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2870 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2874 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2880 int size = sizeof (gpointer);
2883 g_assert (ins->inst_offset % size == 0);
2884 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2886 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2888 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2890 if (ins->flags & MONO_INST_HAS_METHOD) {
2895 * Collect and convert arguments
2897 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2898 len = sizeof (LLVMValueRef) * nargs;
2899 args = (LLVMValueRef*)alloca (len);
2900 memset (args, 0, len);
2901 l = call->out_ireg_args;
2903 if (call->rgctx_arg_reg) {
2904 g_assert (values [call->rgctx_arg_reg]);
2905 g_assert (sinfo.rgctx_arg_pindex < nargs);
2907 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2908 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2909 * it using a volatile load.
2912 if (!ctx->imt_rgctx_loc)
2913 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2914 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2915 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2917 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2920 if (call->imt_arg_reg) {
2921 g_assert (!ctx->llvm_only);
2922 g_assert (values [call->imt_arg_reg]);
2923 g_assert (sinfo.imt_arg_pindex < nargs);
2925 if (!ctx->imt_rgctx_loc)
2926 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2927 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2928 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2930 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2934 if (!addresses [call->inst.dreg])
2935 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2936 g_assert (sinfo.vret_arg_pindex < nargs);
2937 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
2938 args [sinfo.vret_arg_pindex] = addresses [call->inst.dreg];
2940 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2943 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2946 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2950 pindex = sinfo.this_arg_pindex;
2952 pindex = sinfo.pindexes [i - 1];
2954 pindex = sinfo.pindexes [i];
2957 regpair = (guint32)(gssize)(l->data);
2958 reg = regpair & 0xffffff;
2959 args [pindex] = values [reg];
2960 switch (ainfo->storage) {
2961 case LLVMArgVtypeInReg:
2962 case LLVMArgAsFpArgs: {
2965 g_assert (addresses [reg]);
2966 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2970 // FIXME: Get rid of the VMOVE
2973 case LLVMArgVtypeByVal:
2974 g_assert (addresses [reg]);
2975 args [pindex] = addresses [reg];
2977 case LLVMArgVtypeByRef:
2978 g_assert (addresses [reg]);
2979 args [pindex] = addresses [reg];
2981 case LLVMArgAsIArgs:
2982 g_assert (addresses [reg]);
2983 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2985 case LLVMArgVtypeAsScalar:
2986 g_assert_not_reached ();
2989 g_assert (args [pindex]);
2990 if (i == 0 && sig->hasthis)
2991 args [pindex] = convert (ctx, args [pindex], ThisType ());
2993 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2996 g_assert (pindex <= nargs);
3001 // FIXME: Align call sites
3007 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3010 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3012 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3013 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3015 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3016 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3017 if (!sig->pinvoke && !cfg->llvm_only)
3018 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3020 if (cinfo && cinfo->ret.storage == LLVMArgVtypeByRef)
3021 LLVMAddInstrAttribute (lcall, 1 + sinfo.vret_arg_pindex, LLVMStructRetAttribute);
3022 if (!ctx->llvm_only && call->rgctx_arg_reg)
3023 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
3024 if (call->imt_arg_reg)
3025 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
3027 /* Add byval attributes if needed */
3028 for (i = 0; i < sig->param_count; ++i) {
3029 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
3031 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
3032 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
3037 * Convert the result
3040 switch (cinfo->ret.storage) {
3041 case LLVMArgVtypeInReg: {
3042 LLVMValueRef regs [2];
3044 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3048 if (!addresses [ins->dreg])
3049 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3051 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3052 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3053 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3054 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3057 case LLVMArgVtypeByVal:
3058 if (!addresses [call->inst.dreg])
3059 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3060 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3062 case LLVMArgFpStruct:
3063 if (!addresses [call->inst.dreg])
3064 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3065 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3067 case LLVMArgVtypeAsScalar:
3068 if (!addresses [call->inst.dreg])
3069 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3070 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3073 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
3074 /* If the method returns an unsigned value, need to zext it */
3075 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));
3079 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
3080 /* If the method returns an unsigned value, need to zext it */
3081 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));
3085 if (!addresses [call->inst.dreg])
3086 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3087 g_assert (sinfo.vret_arg_pindex < nargs);
3088 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3091 *builder_ref = ctx->builder;
3093 g_free (sinfo.pindexes);
3101 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3103 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3104 LLVMValueRef callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw_icall;
3106 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3109 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3111 if (ctx->cfg->compile_aot) {
3112 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3114 callee = LLVMAddFunction (ctx->module, icall_name, fun_sig);
3115 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3116 mono_memory_barrier ();
3119 ctx->lmodule->rethrow = callee;
3121 ctx->lmodule->throw_icall = callee;
3125 LLVMValueRef args [2];
3127 args [0] = convert (ctx, exc, exc_type);
3128 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3130 LLVMBuildUnreachable (ctx->builder);
3132 ctx->builder = create_builder (ctx);
3136 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3138 MonoMethodSignature *throw_sig;
3139 LLVMValueRef callee, arg;
3140 const char *icall_name;
3142 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw_icall;
3143 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3146 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3147 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3148 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3149 if (ctx->cfg->compile_aot) {
3150 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3152 callee = LLVMAddFunction (ctx->module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3156 * LLVM doesn't push the exception argument, so we need a different
3159 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3161 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3165 mono_memory_barrier ();
3167 ctx->lmodule->rethrow = callee;
3169 ctx->lmodule->throw_icall = callee;
3171 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3172 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3176 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3178 const char *icall_name = "mono_llvm_resume_exception";
3179 LLVMValueRef callee = ctx->lmodule->resume_eh;
3181 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3184 if (ctx->cfg->compile_aot) {
3185 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3187 callee = LLVMAddFunction (ctx->module, icall_name, fun_sig);
3188 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3189 mono_memory_barrier ();
3191 ctx->lmodule->resume_eh = callee;
3195 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3197 LLVMBuildUnreachable (ctx->builder);
3199 ctx->builder = create_builder (ctx);
3203 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3205 const char *icall_name = "mono_llvm_clear_exception";
3207 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3208 LLVMValueRef callee = NULL;
3211 if (ctx->cfg->compile_aot) {
3212 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3214 // FIXME: This is broken.
3215 callee = LLVMAddFunction (ctx->module, icall_name, call_sig);
3219 g_assert (builder && callee);
3221 return LLVMBuildCall (builder, callee, NULL, 0, "");
3225 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3227 const char *icall_name = "mono_llvm_load_exception";
3229 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3230 LLVMValueRef callee = NULL;
3233 if (ctx->cfg->compile_aot) {
3234 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3236 // FIXME: This is broken.
3237 callee = LLVMAddFunction (ctx->module, icall_name, call_sig);
3241 g_assert (builder && callee);
3243 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3248 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3250 const char *icall_name = "mono_llvm_match_exception";
3252 ctx->builder = builder;
3254 const int num_args = 3;
3255 LLVMValueRef args [num_args];
3256 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3257 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3258 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3260 LLVMTypeRef match_sig = LLVMFunctionType3 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), FALSE);
3261 LLVMValueRef callee = ctx->lmodule->match_exc;
3264 if (ctx->cfg->compile_aot) {
3265 ctx->builder = builder;
3266 // get_callee expects ctx->builder to be the emitting builder
3267 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3269 callee = ctx->lmodule->match_exc = LLVMAddFunction (ctx->module, icall_name, match_sig);
3270 LLVMAddGlobalMapping (ctx->lmodule->ee, ctx->lmodule->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3271 ctx->lmodule->match_exc = callee;
3272 mono_memory_barrier ();
3276 g_assert (builder && callee);
3278 g_assert (ctx->ex_var);
3280 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3283 // FIXME: This won't work because the code-finding makes this
3285 /*#define MONO_PERSONALITY_DEBUG*/
3287 mono_debug_personality (int a, _Unwind_Action b,
3288 uint64_t c, struct _Unwind_Exception *d, struct _Unwind_Context *e)
3290 g_assert_not_reached ();
3293 #ifdef MONO_PERSONALITY_DEBUG
3294 static const gboolean use_debug_personality = TRUE;
3295 static const char *default_personality_name = "mono_debug_personality";
3297 static const gboolean use_debug_personality = FALSE;
3298 static const char *default_personality_name = "__gxx_personality_v0";
3302 default_cpp_lpad_exc_signature (void)
3304 static gboolean inited = FALSE;
3305 static LLVMTypeRef sig;
3308 LLVMTypeRef signature [2];
3309 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3310 signature [1] = LLVMInt32Type ();
3311 sig = LLVMStructType (signature, 2, FALSE);
3319 get_mono_personality (EmitContext *ctx)
3321 LLVMValueRef personality = NULL;
3322 static gint32 mapping_inited = FALSE;
3323 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3325 if (!use_debug_personality) {
3326 if (ctx->cfg->compile_aot) {
3327 personality = LLVMGetNamedFunction (ctx->module, default_personality_name);
3328 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3329 personality = LLVMAddFunction (ctx->module, default_personality_name, personality_type);
3330 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, personality);
3333 if (ctx->cfg->compile_aot) {
3334 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3336 personality = LLVMAddFunction (ctx->module, default_personality_name, personality_type);
3337 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3338 mono_memory_barrier ();
3342 g_assert (personality);
3346 static LLVMBasicBlockRef
3347 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3349 MonoCompile *cfg = ctx->cfg;
3350 LLVMBuilderRef old_builder = ctx->builder;
3351 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3353 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3354 ctx->builder = lpadBuilder;
3356 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3357 g_assert (handler_bb);
3359 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3360 LLVMValueRef personality = get_mono_personality (ctx);
3361 g_assert (personality);
3363 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3364 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3366 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3367 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3368 g_assert (landing_pad);
3370 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->lmodule->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3371 LLVMAddClause (landing_pad, cast);
3373 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3374 LLVMBuilderRef resume_builder = create_builder (ctx);
3375 ctx->builder = resume_builder;
3376 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3378 emit_resume_eh (ctx, handler_bb);
3381 ctx->builder = lpadBuilder;
3382 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3384 gboolean finally_only = TRUE;
3386 MonoExceptionClause *group_cursor = group_start;
3388 for (int i = 0; i < group_size; i ++) {
3389 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3390 finally_only = FALSE;
3396 // Handle landing pad inlining
3398 if (!finally_only) {
3399 // So at each level of the exception stack we will match the exception again.
3400 // During that match, we need to compare against the handler types for the current
3401 // protected region. We send the try start and end so that we can only check against
3402 // handlers for this lexical protected region.
3403 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3405 // if returns -1, resume
3406 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3408 // else move to that target bb
3409 for (int i=0; i < group_size; i++) {
3410 MonoExceptionClause *clause = group_start + i;
3411 int clause_index = clause - cfg->header->clauses;
3412 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3413 g_assert (handler_bb);
3414 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3415 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3418 int clause_index = group_start - cfg->header->clauses;
3419 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3420 g_assert (finally_bb);
3422 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3425 ctx->builder = old_builder;
3432 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3434 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3435 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3437 // Make exception available to catch blocks
3438 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3439 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3441 g_assert (ctx->ex_var);
3442 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3444 if (bb->in_scount == 1) {
3445 MonoInst *exvar = bb->in_stack [0];
3446 g_assert (!ctx->values [exvar->dreg]);
3447 g_assert (ctx->ex_var);
3448 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3449 emit_volatile_store (ctx, exvar->dreg);
3452 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3455 LLVMBuilderRef handler_builder = create_builder (ctx);
3456 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3457 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3459 // Make the handler code end with a jump to cbb
3460 LLVMBuildBr (handler_builder, cbb);
3464 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3466 MonoCompile *cfg = ctx->cfg;
3467 LLVMValueRef *values = ctx->values;
3468 LLVMModuleRef module = ctx->module;
3469 BBInfo *bblocks = ctx->bblocks;
3471 LLVMValueRef personality;
3472 LLVMValueRef landing_pad;
3473 LLVMBasicBlockRef target_bb;
3475 static gint32 mapping_inited;
3476 static int ti_generator;
3479 LLVMValueRef type_info;
3483 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3485 if (cfg->compile_aot) {
3486 /* Use a dummy personality function */
3487 personality = LLVMGetNamedFunction (module, "mono_personality");
3488 g_assert (personality);
3490 personality = LLVMGetNamedFunction (module, "mono_personality");
3491 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3492 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
3495 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3497 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3500 * Create the type info
3502 sprintf (ti_name, "type_info_%d", ti_generator);
3505 if (cfg->compile_aot) {
3506 /* decode_eh_frame () in aot-runtime.c will decode this */
3507 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
3508 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3511 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3513 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3516 * After the cfg mempool is freed, the type info will point to stale memory,
3517 * but this is not a problem, since we decode it once in exception_cb during
3520 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3521 *(gint32*)ti = clause_index;
3523 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
3525 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
3529 LLVMTypeRef members [2], ret_type;
3531 members [0] = i8ptr;
3532 members [1] = LLVMInt32Type ();
3533 ret_type = LLVMStructType (members, 2, FALSE);
3535 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3536 LLVMAddClause (landing_pad, type_info);
3538 /* Store the exception into the exvar */
3540 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3544 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3545 * code expects control to be transferred to this landing pad even in the
3546 * presence of nested clauses. The landing pad needs to branch to the landing
3547 * pads belonging to nested clauses based on the selector value returned by
3548 * the landing pad instruction, which is passed to the landing pad in a
3549 * register by the EH code.
3551 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3552 g_assert (target_bb);
3555 * Branch to the correct landing pad
3557 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3558 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3560 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3561 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3562 MonoBasicBlock *handler_bb;
3564 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3565 g_assert (handler_bb);
3567 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3568 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3571 /* Start a new bblock which CALL_HANDLER can branch to */
3572 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3574 ctx->builder = builder = create_builder (ctx);
3575 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3577 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3579 /* Store the exception into the IL level exvar */
3580 if (bb->in_scount == 1) {
3581 g_assert (bb->in_scount == 1);
3582 exvar = bb->in_stack [0];
3584 // FIXME: This is shared with filter clauses ?
3585 g_assert (!values [exvar->dreg]);
3587 g_assert (ctx->ex_var);
3588 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3589 emit_volatile_store (ctx, exvar->dreg);
3595 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3597 MonoCompile *cfg = ctx->cfg;
3598 MonoMethodSignature *sig = ctx->sig;
3599 LLVMValueRef method = ctx->lmethod;
3600 LLVMValueRef *values = ctx->values;
3601 LLVMValueRef *addresses = ctx->addresses;
3602 LLVMCallInfo *linfo = ctx->linfo;
3603 LLVMModuleRef module = ctx->module;
3604 BBInfo *bblocks = ctx->bblocks;
3606 LLVMBasicBlockRef cbb;
3607 LLVMBuilderRef builder, starting_builder;
3608 gboolean has_terminator;
3610 LLVMValueRef lhs, rhs;
3613 if (bb == cfg->bb_entry && ctx->entry_out_bb)
3614 cbb = ctx->entry_out_bb;
3616 cbb = get_bb (ctx, bb);
3618 builder = create_builder (ctx);
3619 ctx->builder = builder;
3620 LLVMPositionBuilderAtEnd (builder, cbb);
3622 CHECK_FAILURE (ctx);
3624 if (bb->flags & BB_EXCEPTION_HANDLER) {
3625 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3626 LLVM_FAILURE (ctx, "handler without invokes");
3630 emit_llvmonly_handler_start (ctx, bb, cbb);
3632 emit_handler_start (ctx, bb, builder);
3633 CHECK_FAILURE (ctx);
3634 builder = ctx->builder;
3637 has_terminator = FALSE;
3638 starting_builder = builder;
3639 for (ins = bb->code; ins; ins = ins->next) {
3640 const char *spec = LLVM_INS_INFO (ins->opcode);
3642 char dname_buf [128];
3644 emit_dbg_loc (ctx, builder, ins->cil_code);
3647 if (nins > 3000 && builder == starting_builder) {
3648 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
3649 LLVM_FAILURE (ctx, "basic block too long");
3653 /* There could be instructions after a terminator, skip them */
3656 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3657 sprintf (dname_buf, "t%d", ins->dreg);
3661 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3662 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3664 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3665 lhs = emit_volatile_load (ctx, ins->sreg1);
3667 /* It is ok for SETRET to have an uninitialized argument */
3668 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
3669 LLVM_FAILURE (ctx, "sreg1");
3670 lhs = values [ins->sreg1];
3676 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
3677 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
3678 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3679 rhs = emit_volatile_load (ctx, ins->sreg2);
3681 if (!values [ins->sreg2])
3682 LLVM_FAILURE (ctx, "sreg2");
3683 rhs = values [ins->sreg2];
3689 //mono_print_ins (ins);
3690 switch (ins->opcode) {
3693 case OP_LIVERANGE_START:
3694 case OP_LIVERANGE_END:
3697 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
3700 #if SIZEOF_VOID_P == 4
3701 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3703 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
3707 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
3711 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
3713 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
3715 case OP_DUMMY_ICONST:
3716 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3718 case OP_DUMMY_I8CONST:
3719 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
3721 case OP_DUMMY_R8CONST:
3722 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
3725 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
3726 LLVMBuildBr (builder, target_bb);
3727 has_terminator = TRUE;
3734 LLVMBasicBlockRef new_bb;
3735 LLVMBuilderRef new_builder;
3737 // The default branch is already handled
3738 // FIXME: Handle it here
3740 /* Start new bblock */
3741 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
3742 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
3744 lhs = convert (ctx, lhs, LLVMInt32Type ());
3745 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
3746 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
3747 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
3749 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
3752 new_builder = create_builder (ctx);
3753 LLVMPositionBuilderAtEnd (new_builder, new_bb);
3754 LLVMBuildUnreachable (new_builder);
3756 has_terminator = TRUE;
3757 g_assert (!ins->next);
3763 switch (linfo->ret.storage) {
3764 case LLVMArgVtypeInReg: {
3765 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3766 LLVMValueRef part1, retval;
3769 size = get_vtype_size (sig->ret);
3771 g_assert (addresses [ins->sreg1]);
3773 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
3774 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
3776 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
3778 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
3780 LLVMBuildRet (builder, retval);
3783 case LLVMArgVtypeAsScalar: {
3784 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3785 LLVMValueRef retval;
3788 size = get_vtype_size (sig->ret);
3790 g_assert (addresses [ins->sreg1]);
3792 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
3793 LLVMBuildRet (builder, retval);
3796 case LLVMArgVtypeByVal: {
3797 LLVMValueRef retval;
3799 g_assert (addresses [ins->sreg1]);
3800 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
3801 LLVMBuildRet (builder, retval);
3804 case LLVMArgVtypeByRef: {
3805 LLVMBuildRetVoid (builder);
3808 case LLVMArgVtypeRetAddr: {
3809 LLVMBuildRetVoid (builder);
3812 case LLVMArgFpStruct: {
3813 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3814 LLVMValueRef retval;
3816 g_assert (addresses [ins->sreg1]);
3817 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
3818 LLVMBuildRet (builder, retval);
3822 if (!lhs || ctx->is_dead [ins->sreg1]) {
3824 * The method did not set its return value, probably because it
3825 * ends with a throw.
3828 LLVMBuildRetVoid (builder);
3830 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
3832 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
3834 has_terminator = TRUE;
3844 case OP_ICOMPARE_IMM:
3845 case OP_LCOMPARE_IMM:
3846 case OP_COMPARE_IMM: {
3850 if (ins->next->opcode == OP_NOP)
3853 if (ins->next->opcode == OP_BR)
3854 /* The comparison result is not needed */
3857 rel = mono_opcode_to_cond (ins->next->opcode);
3859 if (ins->opcode == OP_ICOMPARE_IMM) {
3860 lhs = convert (ctx, lhs, LLVMInt32Type ());
3861 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3863 if (ins->opcode == OP_LCOMPARE_IMM) {
3864 lhs = convert (ctx, lhs, LLVMInt64Type ());
3865 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3867 if (ins->opcode == OP_LCOMPARE) {
3868 lhs = convert (ctx, lhs, LLVMInt64Type ());
3869 rhs = convert (ctx, rhs, LLVMInt64Type ());
3871 if (ins->opcode == OP_ICOMPARE) {
3872 lhs = convert (ctx, lhs, LLVMInt32Type ());
3873 rhs = convert (ctx, rhs, LLVMInt32Type ());
3877 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3878 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
3879 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
3880 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
3883 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
3884 if (ins->opcode == OP_FCOMPARE) {
3885 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3886 } else if (ins->opcode == OP_RCOMPARE) {
3887 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3888 } else if (ins->opcode == OP_COMPARE_IMM) {
3889 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
3890 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
3892 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
3893 } else if (ins->opcode == OP_LCOMPARE_IMM) {
3894 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
3895 /* The immediate is encoded in two fields */
3896 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
3897 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
3899 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
3902 else if (ins->opcode == OP_COMPARE) {
3903 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
3904 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3906 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
3908 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
3910 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
3911 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
3913 * If the target bb contains PHI instructions, LLVM requires
3914 * two PHI entries for this bblock, while we only generate one.
3915 * So convert this to an unconditional bblock. (bxc #171).
3917 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
3919 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
3921 has_terminator = TRUE;
3922 } else if (MONO_IS_SETCC (ins->next)) {
3923 sprintf (dname_buf, "t%d", ins->next->dreg);
3925 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3927 /* Add stores for volatile variables */
3928 emit_volatile_store (ctx, ins->next->dreg);
3929 } else if (MONO_IS_COND_EXC (ins->next)) {
3930 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
3931 CHECK_FAILURE (ctx);
3932 builder = ctx->builder;
3934 LLVM_FAILURE (ctx, "next");
3948 rel = mono_opcode_to_cond (ins->opcode);
3950 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3951 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3962 rel = mono_opcode_to_cond (ins->opcode);
3964 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3965 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3973 gboolean empty = TRUE;
3975 /* Check that all input bblocks really branch to us */
3976 for (i = 0; i < bb->in_count; ++i) {
3977 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3978 ins->inst_phi_args [i + 1] = -1;
3984 /* LLVM doesn't like phi instructions with zero operands */
3985 ctx->is_dead [ins->dreg] = TRUE;
3989 /* Created earlier, insert it now */
3990 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3992 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3993 int sreg1 = ins->inst_phi_args [i + 1];
3997 * Count the number of times the incoming bblock branches to us,
3998 * since llvm requires a separate entry for each.
4000 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4001 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4004 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4005 if (switch_ins->inst_many_bb [j] == bb)
4012 /* Remember for later */
4013 for (j = 0; j < count; ++j) {
4014 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4017 node->in_bb = bb->in_bb [i];
4019 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);
4029 values [ins->dreg] = lhs;
4033 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4036 values [ins->dreg] = lhs;
4038 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4040 * This is added by the spilling pass in case of the JIT,
4041 * but we have to do it ourselves.
4043 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4047 case OP_MOVE_F_TO_I4: {
4048 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4051 case OP_MOVE_I4_TO_F: {
4052 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4055 case OP_MOVE_F_TO_I8: {
4056 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4059 case OP_MOVE_I8_TO_F: {
4060 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4093 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4094 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4096 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4097 CHECK_FAILURE (ctx);
4098 builder = ctx->builder;
4100 switch (ins->opcode) {
4103 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4107 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4111 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4115 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4119 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4123 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4127 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4131 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4135 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4139 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4143 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4147 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4151 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4155 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4159 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4162 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4165 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4169 g_assert_not_reached ();
4176 lhs = convert (ctx, lhs, LLVMFloatType ());
4177 rhs = convert (ctx, rhs, LLVMFloatType ());
4178 switch (ins->opcode) {
4180 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4183 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4186 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4189 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4192 g_assert_not_reached ();
4201 case OP_IREM_UN_IMM:
4203 case OP_IDIV_UN_IMM:
4209 case OP_ISHR_UN_IMM:
4218 case OP_LSHR_UN_IMM:
4224 case OP_SHR_UN_IMM: {
4227 if (spec [MONO_INST_SRC1] == 'l') {
4228 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4230 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4233 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4234 CHECK_FAILURE (ctx);
4235 builder = ctx->builder;
4237 #if SIZEOF_VOID_P == 4
4238 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4239 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4242 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4243 lhs = convert (ctx, lhs, IntPtrType ());
4244 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4245 switch (ins->opcode) {
4249 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4253 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4257 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4261 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4263 case OP_IDIV_UN_IMM:
4264 case OP_LDIV_UN_IMM:
4265 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4269 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4271 case OP_IREM_UN_IMM:
4272 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4277 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4281 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4285 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4290 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4295 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4297 case OP_ISHR_UN_IMM:
4298 /* This is used to implement conv.u4, so the lhs could be an i8 */
4299 lhs = convert (ctx, lhs, LLVMInt32Type ());
4300 imm = convert (ctx, imm, LLVMInt32Type ());
4301 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4303 case OP_LSHR_UN_IMM:
4305 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4308 g_assert_not_reached ();
4313 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4316 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4319 lhs = convert (ctx, lhs, LLVMDoubleType ());
4320 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4323 lhs = convert (ctx, lhs, LLVMFloatType ());
4324 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4327 guint32 v = 0xffffffff;
4328 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4332 guint64 v = 0xffffffffffffffffLL;
4333 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4336 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4338 LLVMValueRef v1, v2;
4340 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4341 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4342 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4347 case OP_ICONV_TO_I1:
4348 case OP_ICONV_TO_I2:
4349 case OP_ICONV_TO_I4:
4350 case OP_ICONV_TO_U1:
4351 case OP_ICONV_TO_U2:
4352 case OP_ICONV_TO_U4:
4353 case OP_LCONV_TO_I1:
4354 case OP_LCONV_TO_I2:
4355 case OP_LCONV_TO_U1:
4356 case OP_LCONV_TO_U2:
4357 case OP_LCONV_TO_U4: {
4360 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);
4362 /* Have to do two casts since our vregs have type int */
4363 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4365 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4367 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4370 case OP_ICONV_TO_I8:
4371 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4373 case OP_ICONV_TO_U8:
4374 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4376 case OP_FCONV_TO_I4:
4377 case OP_RCONV_TO_I4:
4378 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4380 case OP_FCONV_TO_I1:
4381 case OP_RCONV_TO_I1:
4382 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4384 case OP_FCONV_TO_U1:
4385 case OP_RCONV_TO_U1:
4386 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4388 case OP_FCONV_TO_I2:
4389 case OP_RCONV_TO_I2:
4390 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4392 case OP_FCONV_TO_U2:
4393 case OP_RCONV_TO_U2:
4394 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4396 case OP_FCONV_TO_I8:
4397 case OP_RCONV_TO_I8:
4398 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4401 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4403 case OP_ICONV_TO_R8:
4404 case OP_LCONV_TO_R8:
4405 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4407 case OP_ICONV_TO_R_UN:
4408 case OP_LCONV_TO_R_UN:
4409 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4411 #if SIZEOF_VOID_P == 4
4414 case OP_LCONV_TO_I4:
4415 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4417 case OP_ICONV_TO_R4:
4418 case OP_LCONV_TO_R4:
4419 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4421 values [ins->dreg] = v;
4423 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4425 case OP_FCONV_TO_R4:
4426 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4428 values [ins->dreg] = v;
4430 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4432 case OP_RCONV_TO_R8:
4433 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4435 case OP_RCONV_TO_R4:
4436 values [ins->dreg] = lhs;
4439 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4442 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4445 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4447 case OP_LOCALLOC_IMM: {
4450 guint32 size = ins->inst_imm;
4451 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4453 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4455 if (ins->flags & MONO_INST_INIT) {
4456 LLVMValueRef args [5];
4459 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4460 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4461 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4462 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4463 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4466 values [ins->dreg] = v;
4470 LLVMValueRef v, size;
4472 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), "");
4474 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4476 if (ins->flags & MONO_INST_INIT) {
4477 LLVMValueRef args [5];
4480 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4482 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4483 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4484 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4486 values [ins->dreg] = v;
4490 case OP_LOADI1_MEMBASE:
4491 case OP_LOADU1_MEMBASE:
4492 case OP_LOADI2_MEMBASE:
4493 case OP_LOADU2_MEMBASE:
4494 case OP_LOADI4_MEMBASE:
4495 case OP_LOADU4_MEMBASE:
4496 case OP_LOADI8_MEMBASE:
4497 case OP_LOADR4_MEMBASE:
4498 case OP_LOADR8_MEMBASE:
4499 case OP_LOAD_MEMBASE:
4507 LLVMValueRef base, index, addr;
4509 gboolean sext = FALSE, zext = FALSE;
4510 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4512 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4517 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)) {
4518 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4523 if (ins->inst_offset == 0) {
4525 } else if (ins->inst_offset % size != 0) {
4526 /* Unaligned load */
4527 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4528 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4530 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4531 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4535 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4537 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4539 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4541 * These will signal LLVM that these loads do not alias any stores, and
4542 * they can't fail, allowing them to be hoisted out of loops.
4544 set_invariant_load_flag (values [ins->dreg]);
4545 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4549 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4551 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4552 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4553 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4557 case OP_STOREI1_MEMBASE_REG:
4558 case OP_STOREI2_MEMBASE_REG:
4559 case OP_STOREI4_MEMBASE_REG:
4560 case OP_STOREI8_MEMBASE_REG:
4561 case OP_STORER4_MEMBASE_REG:
4562 case OP_STORER8_MEMBASE_REG:
4563 case OP_STORE_MEMBASE_REG: {
4565 LLVMValueRef index, addr;
4567 gboolean sext = FALSE, zext = FALSE;
4568 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4570 if (!values [ins->inst_destbasereg])
4571 LLVM_FAILURE (ctx, "inst_destbasereg");
4573 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4575 if (ins->inst_offset % size != 0) {
4576 /* Unaligned store */
4577 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4578 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4580 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4581 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4583 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4587 case OP_STOREI1_MEMBASE_IMM:
4588 case OP_STOREI2_MEMBASE_IMM:
4589 case OP_STOREI4_MEMBASE_IMM:
4590 case OP_STOREI8_MEMBASE_IMM:
4591 case OP_STORE_MEMBASE_IMM: {
4593 LLVMValueRef index, addr;
4595 gboolean sext = FALSE, zext = FALSE;
4596 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4598 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4600 if (ins->inst_offset % size != 0) {
4601 /* Unaligned store */
4602 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4603 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4605 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4606 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4608 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4613 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
4615 case OP_OUTARG_VTRETADDR:
4623 case OP_VOIDCALL_MEMBASE:
4624 case OP_CALL_MEMBASE:
4625 case OP_LCALL_MEMBASE:
4626 case OP_FCALL_MEMBASE:
4627 case OP_RCALL_MEMBASE:
4628 case OP_VCALL_MEMBASE:
4629 case OP_VOIDCALL_REG:
4634 case OP_VCALL_REG: {
4635 process_call (ctx, bb, &builder, ins);
4636 CHECK_FAILURE (ctx);
4641 LLVMValueRef indexes [2];
4643 LLVMValueRef got_entry_addr;
4646 * FIXME: Can't allocate from the cfg mempool since that is freed if
4647 * the LLVM compile fails.
4649 ji = g_new0 (MonoJumpInfo, 1);
4650 ji->type = (MonoJumpInfoType)ins->inst_c1;
4651 ji->data.target = ins->inst_p0;
4653 ji = mono_aot_patch_info_dup (ji);
4655 ji->next = cfg->patch_info;
4656 cfg->patch_info = ji;
4658 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
4659 got_offset = mono_aot_get_got_offset (cfg->patch_info);
4660 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
4662 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4663 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
4664 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
4666 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
4667 set_invariant_load_flag (values [ins->dreg]);
4670 case OP_NOT_REACHED:
4671 LLVMBuildUnreachable (builder);
4672 has_terminator = TRUE;
4673 g_assert (bb->block_num < cfg->max_block_num);
4674 ctx->unreachable [bb->block_num] = TRUE;
4675 /* Might have instructions after this */
4677 MonoInst *next = ins->next;
4679 * FIXME: If later code uses the regs defined by these instructions,
4680 * compilation will fail.
4682 MONO_DELETE_INS (bb, next);
4686 MonoInst *var = ins->inst_i0;
4688 if (var->opcode == OP_VTARG_ADDR) {
4689 /* The variable contains the vtype address */
4690 values [ins->dreg] = values [var->dreg];
4692 values [ins->dreg] = addresses [var->dreg];
4697 LLVMValueRef args [1];
4699 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4700 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
4704 LLVMValueRef args [1];
4706 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4707 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
4711 LLVMValueRef args [1];
4714 /* This no longer seems to happen */
4716 * LLVM optimizes sqrt(nan) into undefined in
4717 * lib/Analysis/ConstantFolding.cpp
4718 * Also, sqrt(NegativeInfinity) is optimized into 0.
4720 LLVM_FAILURE (ctx, "sqrt");
4722 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4723 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
4727 LLVMValueRef args [1];
4729 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4730 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
4744 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4745 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4747 switch (ins->opcode) {
4750 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
4754 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
4758 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
4762 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
4765 g_assert_not_reached ();
4768 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
4771 case OP_ATOMIC_EXCHANGE_I4:
4772 case OP_ATOMIC_EXCHANGE_I8: {
4773 LLVMValueRef args [2];
4776 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
4777 t = LLVMInt32Type ();
4779 t = LLVMInt64Type ();
4781 g_assert (ins->inst_offset == 0);
4783 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
4784 args [1] = convert (ctx, rhs, t);
4786 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
4789 case OP_ATOMIC_ADD_I4:
4790 case OP_ATOMIC_ADD_I8: {
4791 LLVMValueRef args [2];
4794 if (ins->opcode == OP_ATOMIC_ADD_I4)
4795 t = LLVMInt32Type ();
4797 t = LLVMInt64Type ();
4799 g_assert (ins->inst_offset == 0);
4801 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
4802 args [1] = convert (ctx, rhs, t);
4803 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
4806 case OP_ATOMIC_CAS_I4:
4807 case OP_ATOMIC_CAS_I8: {
4808 LLVMValueRef args [3], val;
4811 if (ins->opcode == OP_ATOMIC_CAS_I4)
4812 t = LLVMInt32Type ();
4814 t = LLVMInt64Type ();
4816 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
4818 args [1] = convert (ctx, values [ins->sreg3], t);
4820 args [2] = convert (ctx, values [ins->sreg2], t);
4821 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
4822 /* cmpxchg returns a pair */
4823 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
4826 case OP_MEMORY_BARRIER: {
4827 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
4830 case OP_ATOMIC_LOAD_I1:
4831 case OP_ATOMIC_LOAD_I2:
4832 case OP_ATOMIC_LOAD_I4:
4833 case OP_ATOMIC_LOAD_I8:
4834 case OP_ATOMIC_LOAD_U1:
4835 case OP_ATOMIC_LOAD_U2:
4836 case OP_ATOMIC_LOAD_U4:
4837 case OP_ATOMIC_LOAD_U8:
4838 case OP_ATOMIC_LOAD_R4:
4839 case OP_ATOMIC_LOAD_R8: {
4840 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
4843 gboolean sext, zext;
4845 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4846 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
4847 LLVMValueRef index, addr;
4849 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4854 if (ins->inst_offset != 0) {
4855 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4856 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
4861 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4863 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
4866 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4868 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4871 case OP_ATOMIC_STORE_I1:
4872 case OP_ATOMIC_STORE_I2:
4873 case OP_ATOMIC_STORE_I4:
4874 case OP_ATOMIC_STORE_I8:
4875 case OP_ATOMIC_STORE_U1:
4876 case OP_ATOMIC_STORE_U2:
4877 case OP_ATOMIC_STORE_U4:
4878 case OP_ATOMIC_STORE_U8:
4879 case OP_ATOMIC_STORE_R4:
4880 case OP_ATOMIC_STORE_R8: {
4881 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
4884 gboolean sext, zext;
4886 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4887 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
4888 LLVMValueRef index, addr, value;
4890 if (!values [ins->inst_destbasereg])
4891 LLVM_FAILURE (ctx, "inst_destbasereg");
4893 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4895 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4896 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4897 value = convert (ctx, values [ins->sreg1], t);
4899 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
4902 case OP_RELAXED_NOP: {
4903 #if defined(TARGET_AMD64) || defined(TARGET_X86)
4904 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
4911 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
4913 // 257 == FS segment register
4914 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
4916 // 256 == GS segment register
4917 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4920 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
4921 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
4922 /* See mono_amd64_emit_tls_get () */
4923 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
4925 // 256 == GS segment register
4926 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4927 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
4929 LLVM_FAILURE (ctx, "opcode tls-get");
4934 case OP_TLS_GET_REG: {
4935 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4936 /* See emit_tls_get_reg () */
4937 // 256 == GS segment register
4938 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4939 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
4941 LLVM_FAILURE (ctx, "opcode tls-get");
4946 case OP_TLS_SET_REG: {
4947 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4948 /* See emit_tls_get_reg () */
4949 // 256 == GS segment register
4950 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4951 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
4953 LLVM_FAILURE (ctx, "opcode tls-set-reg");
4962 case OP_IADD_OVF_UN:
4964 case OP_ISUB_OVF_UN:
4966 case OP_IMUL_OVF_UN:
4967 #if SIZEOF_VOID_P == 8
4969 case OP_LADD_OVF_UN:
4971 case OP_LSUB_OVF_UN:
4973 case OP_LMUL_OVF_UN:
4976 LLVMValueRef args [2], val, ovf, func;
4978 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4979 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4980 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4982 val = LLVMBuildCall (builder, func, args, 2, "");
4983 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4984 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4985 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4986 CHECK_FAILURE (ctx);
4987 builder = ctx->builder;
4993 * We currently model them using arrays. Promotion to local vregs is
4994 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4995 * so we always have an entry in cfg->varinfo for them.
4996 * FIXME: Is this needed ?
4999 MonoClass *klass = ins->klass;
5000 LLVMValueRef args [5];
5004 LLVM_FAILURE (ctx, "!klass");
5008 if (!addresses [ins->dreg])
5009 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5010 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5011 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5012 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5014 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5015 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5016 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
5019 case OP_DUMMY_VZERO:
5022 case OP_STOREV_MEMBASE:
5023 case OP_LOADV_MEMBASE:
5025 MonoClass *klass = ins->klass;
5026 LLVMValueRef src = NULL, dst, args [5];
5027 gboolean done = FALSE;
5031 LLVM_FAILURE (ctx, "!klass");
5035 if (mini_is_gsharedvt_klass (klass)) {
5037 LLVM_FAILURE (ctx, "gsharedvt");
5041 switch (ins->opcode) {
5042 case OP_STOREV_MEMBASE:
5043 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5044 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5045 /* Decomposed earlier */
5046 g_assert_not_reached ();
5049 if (!addresses [ins->sreg1]) {
5051 g_assert (values [ins->sreg1]);
5052 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));
5053 LLVMBuildStore (builder, values [ins->sreg1], dst);
5056 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5057 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5060 case OP_LOADV_MEMBASE:
5061 if (!addresses [ins->dreg])
5062 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5063 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5064 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5067 if (!addresses [ins->sreg1])
5068 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5069 if (!addresses [ins->dreg])
5070 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5071 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5072 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5075 g_assert_not_reached ();
5077 CHECK_FAILURE (ctx);
5084 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5085 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5087 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5088 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5089 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
5092 case OP_LLVM_OUTARG_VT:
5093 if (!addresses [ins->sreg1]) {
5094 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
5095 g_assert (values [ins->sreg1]);
5096 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
5098 addresses [ins->dreg] = addresses [ins->sreg1];
5104 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5106 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5109 case OP_LOADX_MEMBASE: {
5110 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5113 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5114 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5117 case OP_STOREX_MEMBASE: {
5118 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5121 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5122 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5129 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5133 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5139 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5143 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5147 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5151 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5154 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5157 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5160 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5164 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5175 LLVMValueRef v = NULL;
5177 switch (ins->opcode) {
5182 t = LLVMVectorType (LLVMInt32Type (), 4);
5183 rt = LLVMVectorType (LLVMFloatType (), 4);
5189 t = LLVMVectorType (LLVMInt64Type (), 2);
5190 rt = LLVMVectorType (LLVMDoubleType (), 2);
5193 t = LLVMInt32Type ();
5194 rt = LLVMInt32Type ();
5195 g_assert_not_reached ();
5198 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5199 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5200 switch (ins->opcode) {
5203 v = LLVMBuildAnd (builder, lhs, rhs, "");
5207 v = LLVMBuildOr (builder, lhs, rhs, "");
5211 v = LLVMBuildXor (builder, lhs, rhs, "");
5215 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5218 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5242 case OP_PADDB_SAT_UN:
5243 case OP_PADDW_SAT_UN:
5244 case OP_PSUBB_SAT_UN:
5245 case OP_PSUBW_SAT_UN:
5253 case OP_PMULW_HIGH_UN: {
5254 LLVMValueRef args [2];
5259 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5266 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5270 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5278 case OP_EXTRACTX_U2:
5280 case OP_EXTRACT_U1: {
5282 gboolean zext = FALSE;
5284 t = simd_op_to_llvm_type (ins->opcode);
5286 switch (ins->opcode) {
5294 case OP_EXTRACTX_U2:
5299 t = LLVMInt32Type ();
5300 g_assert_not_reached ();
5303 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5304 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5306 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5315 case OP_EXPAND_R8: {
5316 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5317 LLVMValueRef mask [16], v;
5320 for (i = 0; i < 16; ++i)
5321 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5323 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5325 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5326 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5331 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5334 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5337 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5340 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5343 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5346 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5357 case OP_EXTRACT_MASK:
5364 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5366 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5372 LLVMValueRef args [3];
5376 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5378 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5383 /* This is only used for implementing shifts by non-immediate */
5384 values [ins->dreg] = lhs;
5395 LLVMValueRef args [3];
5398 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5400 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5411 case OP_PSHLQ_REG: {
5412 LLVMValueRef args [3];
5415 args [1] = values [ins->sreg2];
5417 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5424 case OP_PSHUFLEW_LOW:
5425 case OP_PSHUFLEW_HIGH: {
5427 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5428 int i, mask_size = 0;
5429 int imask = ins->inst_c0;
5431 /* Convert the x86 shuffle mask to LLVM's */
5432 switch (ins->opcode) {
5435 mask [0] = ((imask >> 0) & 3);
5436 mask [1] = ((imask >> 2) & 3);
5437 mask [2] = ((imask >> 4) & 3) + 4;
5438 mask [3] = ((imask >> 6) & 3) + 4;
5439 v1 = values [ins->sreg1];
5440 v2 = values [ins->sreg2];
5444 mask [0] = ((imask >> 0) & 1);
5445 mask [1] = ((imask >> 1) & 1) + 2;
5446 v1 = values [ins->sreg1];
5447 v2 = values [ins->sreg2];
5449 case OP_PSHUFLEW_LOW:
5451 mask [0] = ((imask >> 0) & 3);
5452 mask [1] = ((imask >> 2) & 3);
5453 mask [2] = ((imask >> 4) & 3);
5454 mask [3] = ((imask >> 6) & 3);
5459 v1 = values [ins->sreg1];
5460 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5462 case OP_PSHUFLEW_HIGH:
5468 mask [4] = 4 + ((imask >> 0) & 3);
5469 mask [5] = 4 + ((imask >> 2) & 3);
5470 mask [6] = 4 + ((imask >> 4) & 3);
5471 mask [7] = 4 + ((imask >> 6) & 3);
5472 v1 = values [ins->sreg1];
5473 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5477 mask [0] = ((imask >> 0) & 3);
5478 mask [1] = ((imask >> 2) & 3);
5479 mask [2] = ((imask >> 4) & 3);
5480 mask [3] = ((imask >> 6) & 3);
5481 v1 = values [ins->sreg1];
5482 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5485 g_assert_not_reached ();
5487 for (i = 0; i < mask_size; ++i)
5488 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5490 values [ins->dreg] =
5491 LLVMBuildShuffleVector (builder, v1, v2,
5492 LLVMConstVector (mask_values, mask_size), dname);
5496 case OP_UNPACK_LOWB:
5497 case OP_UNPACK_LOWW:
5498 case OP_UNPACK_LOWD:
5499 case OP_UNPACK_LOWQ:
5500 case OP_UNPACK_LOWPS:
5501 case OP_UNPACK_LOWPD:
5502 case OP_UNPACK_HIGHB:
5503 case OP_UNPACK_HIGHW:
5504 case OP_UNPACK_HIGHD:
5505 case OP_UNPACK_HIGHQ:
5506 case OP_UNPACK_HIGHPS:
5507 case OP_UNPACK_HIGHPD: {
5509 LLVMValueRef mask_values [16];
5510 int i, mask_size = 0;
5511 gboolean low = FALSE;
5513 switch (ins->opcode) {
5514 case OP_UNPACK_LOWB:
5518 case OP_UNPACK_LOWW:
5522 case OP_UNPACK_LOWD:
5523 case OP_UNPACK_LOWPS:
5527 case OP_UNPACK_LOWQ:
5528 case OP_UNPACK_LOWPD:
5532 case OP_UNPACK_HIGHB:
5535 case OP_UNPACK_HIGHW:
5538 case OP_UNPACK_HIGHD:
5539 case OP_UNPACK_HIGHPS:
5542 case OP_UNPACK_HIGHQ:
5543 case OP_UNPACK_HIGHPD:
5547 g_assert_not_reached ();
5551 for (i = 0; i < (mask_size / 2); ++i) {
5553 mask [(i * 2) + 1] = mask_size + i;
5556 for (i = 0; i < (mask_size / 2); ++i) {
5557 mask [(i * 2)] = (mask_size / 2) + i;
5558 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
5562 for (i = 0; i < mask_size; ++i)
5563 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5565 values [ins->dreg] =
5566 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
5567 LLVMConstVector (mask_values, mask_size), dname);
5572 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5573 LLVMValueRef v, val;
5575 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5576 val = LLVMConstNull (t);
5577 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5578 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
5580 values [ins->dreg] = val;
5584 case OP_DUPPS_HIGH: {
5585 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5586 LLVMValueRef v1, v2, val;
5589 if (ins->opcode == OP_DUPPS_LOW) {
5590 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5591 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5593 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5594 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5596 val = LLVMConstNull (t);
5597 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5598 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5599 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5600 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5602 values [ins->dreg] = val;
5612 * EXCEPTION HANDLING
5614 case OP_IMPLICIT_EXCEPTION:
5615 /* This marks a place where an implicit exception can happen */
5616 if (bb->region != -1)
5617 LLVM_FAILURE (ctx, "implicit-exception");
5621 gboolean rethrow = (ins->opcode == OP_RETHROW);
5622 if (ctx->llvm_only) {
5623 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
5624 has_terminator = TRUE;
5625 ctx->unreachable [bb->block_num] = TRUE;
5627 emit_throw (ctx, bb, rethrow, lhs);
5628 builder = ctx->builder;
5632 case OP_CALL_HANDLER: {
5634 * We don't 'call' handlers, but instead simply branch to them.
5635 * The code generated by ENDFINALLY will branch back to us.
5637 LLVMBasicBlockRef noex_bb;
5639 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
5641 bb_list = info->call_handler_return_bbs;
5644 * Set the indicator variable for the finally clause.
5646 lhs = info->finally_ind;
5648 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
5650 /* Branch to the finally clause */
5651 LLVMBuildBr (builder, info->call_handler_target_bb);
5653 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
5654 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
5656 builder = ctx->builder = create_builder (ctx);
5657 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
5659 bblocks [bb->block_num].end_bblock = noex_bb;
5662 case OP_START_HANDLER: {
5665 case OP_ENDFINALLY: {
5666 LLVMBasicBlockRef resume_bb;
5667 MonoBasicBlock *handler_bb;
5668 LLVMValueRef val, switch_ins, callee;
5672 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
5673 g_assert (handler_bb);
5674 info = &bblocks [handler_bb->block_num];
5675 lhs = info->finally_ind;
5678 bb_list = info->call_handler_return_bbs;
5680 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
5682 /* Load the finally variable */
5683 val = LLVMBuildLoad (builder, lhs, "");
5685 /* Reset the variable */
5686 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
5688 /* Branch to either resume_bb, or to the bblocks in bb_list */
5689 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
5691 * The other targets are added at the end to handle OP_CALL_HANDLER
5692 * opcodes processed later.
5694 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
5696 builder = ctx->builder = create_builder (ctx);
5697 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
5699 if (ctx->llvm_only) {
5700 emit_resume_eh (ctx, bb);
5702 if (ctx->cfg->compile_aot) {
5703 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
5705 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
5707 LLVMBuildCall (builder, callee, NULL, 0, "");
5708 LLVMBuildUnreachable (builder);
5711 has_terminator = TRUE;
5717 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
5718 LLVM_FAILURE (ctx, reason);
5723 /* Convert the value to the type required by phi nodes */
5724 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
5725 if (!values [ins->dreg])
5727 values [ins->dreg] = addresses [ins->dreg];
5729 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
5732 /* Add stores for volatile variables */
5733 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
5734 emit_volatile_store (ctx, ins->dreg);
5737 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
5738 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
5741 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
5742 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
5743 LLVMBuildRetVoid (builder);
5746 if (bb == cfg->bb_entry)
5747 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
5756 * mono_llvm_check_method_supported:
5758 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
5759 * compiling a method twice.
5762 mono_llvm_check_method_supported (MonoCompile *cfg)
5769 if (cfg->method->save_lmf) {
5770 cfg->exception_message = g_strdup ("lmf");
5771 cfg->disable_llvm = TRUE;
5773 if (cfg->disable_llvm)
5777 * Nested clauses where one of the clauses is a finally clause is
5778 * not supported, because LLVM can't figure out the control flow,
5779 * probably because we resume exception handling by calling our
5780 * own function instead of using the 'resume' llvm instruction.
5782 for (i = 0; i < cfg->header->num_clauses; ++i) {
5783 for (j = 0; j < cfg->header->num_clauses; ++j) {
5784 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
5785 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
5787 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
5788 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
5789 cfg->exception_message = g_strdup ("nested clauses");
5790 cfg->disable_llvm = TRUE;
5795 if (cfg->disable_llvm)
5799 if (cfg->method->dynamic) {
5800 cfg->exception_message = g_strdup ("dynamic.");
5801 cfg->disable_llvm = TRUE;
5803 if (cfg->disable_llvm)
5808 * mono_llvm_emit_method:
5810 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
5813 mono_llvm_emit_method (MonoCompile *cfg)
5816 MonoMethodSignature *sig;
5818 LLVMTypeRef method_type;
5819 LLVMValueRef method = NULL;
5821 LLVMValueRef *values;
5822 int i, max_block_num, bb_index;
5823 gboolean last = FALSE;
5824 GPtrArray *phi_values;
5825 LLVMCallInfo *linfo;
5827 LLVMModuleRef module;
5829 GPtrArray *bblock_list;
5830 MonoMethodHeader *header;
5831 MonoExceptionClause *clause;
5835 /* The code below might acquire the loader lock, so use it for global locking */
5836 mono_loader_lock ();
5838 /* Used to communicate with the callbacks */
5839 mono_native_tls_set_value (current_cfg_tls_id, cfg);
5841 ctx = g_new0 (EmitContext, 1);
5843 ctx->mempool = cfg->mempool;
5846 * This maps vregs to the LLVM instruction defining them
5848 values = g_new0 (LLVMValueRef, cfg->next_vreg);
5850 * This maps vregs for volatile variables to the LLVM instruction defining their
5853 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
5854 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
5855 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
5856 phi_values = g_ptr_array_sized_new (256);
5858 * This signals whenever the vreg was defined by a phi node with no input vars
5859 * (i.e. all its input bblocks end with NOT_REACHABLE).
5861 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
5862 /* Whenever the bblock is unreachable */
5863 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
5864 bblock_list = g_ptr_array_sized_new (256);
5866 ctx->values = values;
5867 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
5868 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
5870 if (cfg->compile_aot) {
5871 ctx->lmodule = &aot_module;
5872 method_name = mono_aot_get_method_name (cfg);
5873 cfg->llvm_method_name = g_strdup (method_name);
5875 init_jit_module (cfg->domain);
5876 ctx->lmodule = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
5877 method_name = mono_method_full_name (cfg->method, TRUE);
5880 module = ctx->module = ctx->lmodule->module;
5881 ctx->llvm_only = ctx->lmodule->llvm_only;
5884 LLVM_FAILURE (ctx, "gsharedvt");
5888 static int count = 0;
5891 if (g_getenv ("LLVM_COUNT")) {
5892 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
5893 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
5897 if (count > atoi (g_getenv ("LLVM_COUNT")))
5898 LLVM_FAILURE (ctx, "");
5903 sig = mono_method_signature (cfg->method);
5906 linfo = mono_arch_get_llvm_call_info (cfg, sig);
5908 CHECK_FAILURE (ctx);
5911 linfo->rgctx_arg = TRUE;
5912 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
5913 CHECK_FAILURE (ctx);
5916 * This maps parameter indexes in the original signature to the indexes in
5917 * the LLVM signature.
5919 ctx->pindexes = sinfo.pindexes;
5921 method = LLVMAddFunction (module, method_name, method_type);
5922 ctx->lmethod = method;
5924 if (!cfg->llvm_only)
5925 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
5926 LLVMSetLinkage (method, LLVMPrivateLinkage);
5928 LLVMAddFunctionAttr (method, LLVMUWTable);
5930 if (cfg->compile_aot) {
5931 LLVMSetLinkage (method, LLVMInternalLinkage);
5932 if (ctx->lmodule->external_symbols) {
5933 LLVMSetLinkage (method, LLVMExternalLinkage);
5934 LLVMSetVisibility (method, LLVMHiddenVisibility);
5937 LLVMSetLinkage (method, LLVMPrivateLinkage);
5940 if (cfg->method->save_lmf && !cfg->llvm_only)
5941 LLVM_FAILURE (ctx, "lmf");
5943 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
5944 LLVM_FAILURE (ctx, "pinvoke signature");
5946 header = cfg->header;
5947 for (i = 0; i < header->num_clauses; ++i) {
5948 clause = &header->clauses [i];
5949 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5950 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5952 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5953 /* We can't handle inlined methods with clauses */
5954 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5956 if (linfo->rgctx_arg) {
5957 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5958 ctx->rgctx_arg_pindex = sinfo.rgctx_arg_pindex;
5960 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5961 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5962 * CC_X86_64_Mono in X86CallingConv.td.
5964 if (!ctx->llvm_only)
5965 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5966 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5968 ctx->rgctx_arg_pindex = -1;
5970 if (cfg->vret_addr) {
5971 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5972 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5973 if (linfo->ret.storage == LLVMArgVtypeByRef) {
5974 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMStructRetAttribute);
5975 LLVMAddAttribute (LLVMGetParam (method, sinfo.vret_arg_pindex), LLVMNoAliasAttribute);
5979 ctx->this_arg_pindex = sinfo.this_arg_pindex;
5980 ctx->this_arg = LLVMGetParam (method, sinfo.this_arg_pindex);
5981 values [cfg->args [0]->dreg] = ctx->this_arg;
5982 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5985 names = g_new (char *, sig->param_count);
5986 mono_method_get_param_names (cfg->method, (const char **) names);
5988 for (i = 0; i < sig->param_count; ++i) {
5991 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5992 if (names [i] && names [i][0] != '\0')
5993 name = g_strdup_printf ("arg_%s", names [i]);
5995 name = g_strdup_printf ("arg_%d", i);
5996 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5998 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5999 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
6001 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByRef) {
6003 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6008 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6009 ctx->minfo = mono_debug_lookup_method (cfg->method);
6010 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6014 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6015 max_block_num = MAX (max_block_num, bb->block_num);
6016 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6018 /* Add branches between non-consecutive bblocks */
6019 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6020 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6021 bb->next_bb != bb->last_ins->inst_false_bb) {
6023 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6024 inst->opcode = OP_BR;
6025 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6026 mono_bblock_add_inst (bb, inst);
6031 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6032 * was later optimized away, so clear these flags, and add them back for the still
6033 * present OP_LDADDR instructions.
6035 for (i = 0; i < cfg->next_vreg; ++i) {
6038 ins = get_vreg_to_inst (cfg, i);
6039 if (ins && ins != cfg->rgctx_var)
6040 ins->flags &= ~MONO_INST_INDIRECT;
6044 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6046 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6048 LLVMBuilderRef builder;
6050 char dname_buf[128];
6052 builder = create_builder (ctx);
6054 for (ins = bb->code; ins; ins = ins->next) {
6055 switch (ins->opcode) {
6060 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6062 CHECK_FAILURE (ctx);
6064 if (ins->opcode == OP_VPHI) {
6065 /* Treat valuetype PHI nodes as operating on the address itself */
6066 g_assert (ins->klass);
6067 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6071 * Have to precreate these, as they can be referenced by
6072 * earlier instructions.
6074 sprintf (dname_buf, "t%d", ins->dreg);
6076 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6078 if (ins->opcode == OP_VPHI)
6079 ctx->addresses [ins->dreg] = values [ins->dreg];
6081 g_ptr_array_add (phi_values, values [ins->dreg]);
6084 * Set the expected type of the incoming arguments since these have
6085 * to have the same type.
6087 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6088 int sreg1 = ins->inst_phi_args [i + 1];
6091 ctx->vreg_types [sreg1] = phi_type;
6096 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6105 * Create an ordering for bblocks, use the depth first order first, then
6106 * put the exception handling bblocks last.
6108 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6109 bb = cfg->bblocks [bb_index];
6110 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6111 g_ptr_array_add (bblock_list, bb);
6112 bblocks [bb->block_num].added = TRUE;
6116 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6117 if (!bblocks [bb->block_num].added)
6118 g_ptr_array_add (bblock_list, bb);
6122 * Second pass: generate code.
6125 LLVMBuilderRef entry_builder = create_builder (ctx);
6126 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6127 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6128 emit_entry_bb (ctx, entry_builder);
6130 // Make landing pads first
6131 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6133 if (ctx->llvm_only) {
6134 size_t group_index = 0;
6135 while (group_index < cfg->header->num_clauses) {
6137 size_t cursor = group_index;
6138 while (cursor < cfg->header->num_clauses &&
6139 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6140 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6145 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6146 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6147 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6149 group_index = cursor;
6153 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6154 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6156 // Prune unreachable mono BBs.
6157 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6160 process_bb (ctx, bb);
6161 CHECK_FAILURE (ctx);
6163 g_hash_table_destroy (ctx->exc_meta);
6165 mono_memory_barrier ();
6167 /* Add incoming phi values */
6168 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6169 GSList *l, *ins_list;
6171 ins_list = bblocks [bb->block_num].phi_nodes;
6173 for (l = ins_list; l; l = l->next) {
6174 PhiNode *node = (PhiNode*)l->data;
6175 MonoInst *phi = node->phi;
6176 int sreg1 = node->sreg;
6177 LLVMBasicBlockRef in_bb;
6182 in_bb = get_end_bb (ctx, node->in_bb);
6184 if (ctx->unreachable [node->in_bb->block_num])
6187 if (!values [sreg1])
6188 /* Can happen with values in EH clauses */
6189 LLVM_FAILURE (ctx, "incoming phi sreg1");
6191 if (phi->opcode == OP_VPHI) {
6192 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6193 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6195 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6197 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6198 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6199 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6204 /* Nullify empty phi instructions */
6205 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6206 GSList *l, *ins_list;
6208 ins_list = bblocks [bb->block_num].phi_nodes;
6210 for (l = ins_list; l; l = l->next) {
6211 PhiNode *node = (PhiNode*)l->data;
6212 MonoInst *phi = node->phi;
6213 LLVMValueRef phi_ins = values [phi->dreg];
6216 /* Already removed */
6219 if (LLVMCountIncoming (phi_ins) == 0) {
6220 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6221 LLVMInstructionEraseFromParent (phi_ins);
6222 values [phi->dreg] = NULL;
6227 /* Create the SWITCH statements for ENDFINALLY instructions */
6228 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6229 BBInfo *info = &bblocks [bb->block_num];
6231 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6232 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6233 GSList *bb_list = info->call_handler_return_bbs;
6235 for (i = 0; i < g_slist_length (bb_list); ++i)
6236 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
6240 if (cfg->verbose_level > 1)
6241 mono_llvm_dump_value (method);
6243 if (cfg->compile_aot)
6244 mark_as_used (ctx->lmodule, method);
6246 if (cfg->compile_aot) {
6247 LLVMValueRef md_args [16];
6248 LLVMValueRef md_node;
6251 method_index = mono_aot_get_method_index (cfg->orig_method);
6252 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6253 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6254 md_node = LLVMMDNode (md_args, 2);
6255 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
6256 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6259 if (cfg->compile_aot) {
6260 /* Don't generate native code, keep the LLVM IR */
6261 if (cfg->verbose_level)
6262 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6264 LLVMVerifyFunction(method, 0);
6266 LLVMVerifyFunction(method, 0);
6267 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
6269 if (cfg->verbose_level > 1)
6270 mono_llvm_dump_value (method);
6272 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
6274 /* Set by emit_cb */
6275 g_assert (cfg->code_len);
6277 /* FIXME: Free the LLVM IL for the function */
6280 if (ctx->lmodule->method_to_lmethod)
6281 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
6282 if (ctx->lmodule->idx_to_lmethod)
6283 g_hash_table_insert (ctx->lmodule->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6285 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6286 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6293 /* Need to add unused phi nodes as they can be referenced by other values */
6294 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6295 LLVMBuilderRef builder;
6297 builder = create_builder (ctx);
6298 LLVMPositionBuilderAtEnd (builder, phi_bb);
6300 for (i = 0; i < phi_values->len; ++i) {
6301 LLVMValueRef v = g_ptr_array_index (phi_values, i);
6302 if (LLVMGetInstructionParent (v) == NULL)
6303 LLVMInsertIntoBuilder (builder, v);
6306 LLVMDeleteFunction (method);
6311 g_free (ctx->addresses);
6312 g_free (ctx->vreg_types);
6313 g_free (ctx->vreg_cli_types);
6314 g_free (ctx->pindexes);
6315 g_free (ctx->is_dead);
6316 g_free (ctx->unreachable);
6317 g_ptr_array_free (phi_values, TRUE);
6318 g_free (ctx->bblocks);
6319 g_hash_table_destroy (ctx->region_to_handler);
6320 g_hash_table_destroy (ctx->clause_to_handler);
6321 g_free (method_name);
6322 g_ptr_array_free (bblock_list, TRUE);
6324 for (l = ctx->builders; l; l = l->next) {
6325 LLVMBuilderRef builder = l->data;
6326 LLVMDisposeBuilder (builder);
6331 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6333 mono_loader_unlock ();
6337 * mono_llvm_emit_call:
6339 * Same as mono_arch_emit_call () for LLVM.
6342 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6345 MonoMethodSignature *sig;
6346 int i, n, stack_size;
6351 sig = call->signature;
6352 n = sig->param_count + sig->hasthis;
6354 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
6356 if (cfg->disable_llvm)
6359 if (sig->call_convention == MONO_CALL_VARARG) {
6360 cfg->exception_message = g_strdup ("varargs");
6361 cfg->disable_llvm = TRUE;
6364 for (i = 0; i < n; ++i) {
6367 ainfo = call->cinfo->args + i;
6369 in = call->args [i];
6371 /* Simply remember the arguments */
6372 switch (ainfo->storage) {
6374 case LLVMArgInFPReg: {
6375 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
6378 opcode = mono_type_to_regmove (cfg, t);
6379 if (opcode == OP_FMOVE) {
6380 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6381 ins->dreg = mono_alloc_freg (cfg);
6382 } else if (opcode == OP_LMOVE) {
6383 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6384 ins->dreg = mono_alloc_lreg (cfg);
6386 MONO_INST_NEW (cfg, ins, OP_MOVE);
6387 ins->dreg = mono_alloc_ireg (cfg);
6389 ins->sreg1 = in->dreg;
6392 case LLVMArgVtypeByVal:
6393 case LLVMArgVtypeByRef:
6394 case LLVMArgVtypeInReg:
6395 case LLVMArgVtypeAsScalar:
6396 case LLVMArgAsIArgs:
6397 case LLVMArgAsFpArgs:
6398 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
6399 ins->dreg = mono_alloc_ireg (cfg);
6400 ins->sreg1 = in->dreg;
6401 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
6404 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
6405 cfg->exception_message = g_strdup ("ainfo->storage");
6406 cfg->disable_llvm = TRUE;
6410 if (!cfg->disable_llvm) {
6411 MONO_ADD_INS (cfg->cbb, ins);
6412 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
6417 static unsigned char*
6418 alloc_cb (LLVMValueRef function, int size)
6422 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6426 return mono_domain_code_reserve (cfg->domain, size);
6428 return mono_domain_code_reserve (mono_domain_get (), size);
6433 emitted_cb (LLVMValueRef function, void *start, void *end)
6437 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6439 cfg->code_len = (guint8*)end - (guint8*)start;
6443 exception_cb (void *data)
6446 MonoJitExceptionInfo *ei;
6447 guint32 ei_len, i, j, nested_len, nindex;
6448 gpointer *type_info;
6449 int this_reg, this_offset;
6451 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6455 * data points to a DWARF FDE structure, convert it to our unwind format and
6457 * An alternative would be to save it directly, and modify our unwinder to work
6460 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);
6461 if (cfg->verbose_level > 1)
6462 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
6464 /* Count nested clauses */
6466 for (i = 0; i < ei_len; ++i) {
6467 gint32 cindex1 = *(gint32*)type_info [i];
6468 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
6470 for (j = 0; j < cfg->header->num_clauses; ++j) {
6472 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
6474 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6480 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
6481 cfg->llvm_ex_info_len = ei_len + nested_len;
6482 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
6483 /* Fill the rest of the information from the type info */
6484 for (i = 0; i < ei_len; ++i) {
6485 gint32 clause_index = *(gint32*)type_info [i];
6486 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
6488 cfg->llvm_ex_info [i].flags = clause->flags;
6489 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
6490 cfg->llvm_ex_info [i].clause_index = clause_index;
6494 * For nested clauses, the LLVM produced exception info associates the try interval with
6495 * the innermost handler, while mono expects it to be associated with all nesting clauses.
6496 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
6497 * and everything else from the nested clause.
6500 for (i = 0; i < ei_len; ++i) {
6501 gint32 cindex1 = *(gint32*)type_info [i];
6502 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
6504 for (j = 0; j < cfg->header->num_clauses; ++j) {
6506 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
6507 MonoJitExceptionInfo *nesting_ei, *nested_ei;
6509 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6510 /* clause1 is the nested clause */
6511 nested_ei = &cfg->llvm_ex_info [i];
6512 nesting_ei = &cfg->llvm_ex_info [nindex];
6515 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
6517 nesting_ei->flags = clause2->flags;
6518 nesting_ei->data.catch_class = clause2->data.catch_class;
6519 nesting_ei->clause_index = cindex2;
6523 g_assert (nindex == ei_len + nested_len);
6524 cfg->llvm_this_reg = this_reg;
6525 cfg->llvm_this_offset = this_offset;
6527 /* type_info [i] is cfg mempool allocated, no need to free it */
6534 dlsym_cb (const char *name, void **symbol)
6540 if (!strcmp (name, "__bzero")) {
6541 *symbol = (void*)bzero;
6543 current = mono_dl_open (NULL, 0, NULL);
6546 err = mono_dl_symbol (current, name, symbol);
6548 mono_dl_close (current);
6550 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
6551 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
6557 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
6559 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
6563 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
6565 LLVMTypeRef param_types [4];
6567 param_types [0] = param_type1;
6568 param_types [1] = param_type2;
6570 AddFunc (module, name, ret_type, param_types, 2);
6574 add_intrinsics (LLVMModuleRef module)
6576 /* Emit declarations of instrinsics */
6578 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
6579 * type doesn't seem to do any locking.
6582 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
6584 memset_param_count = 5;
6585 memset_func_name = "llvm.memset.p0i8.i32";
6587 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
6591 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
6593 memcpy_param_count = 5;
6594 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
6596 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
6600 LLVMTypeRef params [] = { LLVMDoubleType () };
6602 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
6603 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
6604 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
6606 /* This isn't an intrinsic, instead llvm seems to special case it by name */
6607 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
6611 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
6612 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
6613 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
6615 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
6616 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
6617 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
6618 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
6619 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
6620 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
6621 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
6625 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
6626 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
6627 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
6629 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
6630 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
6631 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
6632 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
6633 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
6634 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
6637 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
6641 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
6643 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
6646 /* SSE intrinsics */
6647 #if defined(TARGET_X86) || defined(TARGET_AMD64)
6649 LLVMTypeRef ret_type, arg_types [16];
6652 ret_type = type_to_simd_type (MONO_TYPE_I4);
6653 arg_types [0] = ret_type;
6654 arg_types [1] = ret_type;
6655 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
6656 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
6658 ret_type = type_to_simd_type (MONO_TYPE_I2);
6659 arg_types [0] = ret_type;
6660 arg_types [1] = ret_type;
6661 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
6662 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
6663 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
6664 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
6665 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
6666 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
6667 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
6668 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
6669 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
6670 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
6672 ret_type = type_to_simd_type (MONO_TYPE_I1);
6673 arg_types [0] = ret_type;
6674 arg_types [1] = ret_type;
6675 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
6676 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
6677 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
6678 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
6679 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
6680 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
6681 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
6683 ret_type = type_to_simd_type (MONO_TYPE_R8);
6684 arg_types [0] = ret_type;
6685 arg_types [1] = ret_type;
6686 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
6687 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
6688 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
6689 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
6690 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
6692 ret_type = type_to_simd_type (MONO_TYPE_R4);
6693 arg_types [0] = ret_type;
6694 arg_types [1] = ret_type;
6695 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
6696 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
6697 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
6698 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
6699 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
6702 ret_type = type_to_simd_type (MONO_TYPE_I1);
6703 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
6704 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
6705 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
6706 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
6707 ret_type = type_to_simd_type (MONO_TYPE_I2);
6708 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6709 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
6710 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
6711 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
6714 ret_type = type_to_simd_type (MONO_TYPE_R8);
6715 arg_types [0] = ret_type;
6716 arg_types [1] = ret_type;
6717 arg_types [2] = LLVMInt8Type ();
6718 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
6719 ret_type = type_to_simd_type (MONO_TYPE_R4);
6720 arg_types [0] = ret_type;
6721 arg_types [1] = ret_type;
6722 arg_types [2] = LLVMInt8Type ();
6723 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
6725 /* Conversion ops */
6726 ret_type = type_to_simd_type (MONO_TYPE_R8);
6727 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6728 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
6729 ret_type = type_to_simd_type (MONO_TYPE_R4);
6730 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6731 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
6732 ret_type = type_to_simd_type (MONO_TYPE_I4);
6733 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
6734 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
6735 ret_type = type_to_simd_type (MONO_TYPE_I4);
6736 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
6737 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
6738 ret_type = type_to_simd_type (MONO_TYPE_R4);
6739 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
6740 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
6741 ret_type = type_to_simd_type (MONO_TYPE_R8);
6742 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
6743 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
6745 ret_type = type_to_simd_type (MONO_TYPE_I4);
6746 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
6747 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
6748 ret_type = type_to_simd_type (MONO_TYPE_I4);
6749 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
6750 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
6753 ret_type = type_to_simd_type (MONO_TYPE_R8);
6754 arg_types [0] = ret_type;
6755 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
6756 ret_type = type_to_simd_type (MONO_TYPE_R4);
6757 arg_types [0] = ret_type;
6758 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
6759 ret_type = type_to_simd_type (MONO_TYPE_R4);
6760 arg_types [0] = ret_type;
6761 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
6762 ret_type = type_to_simd_type (MONO_TYPE_R4);
6763 arg_types [0] = ret_type;
6764 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
6767 ret_type = type_to_simd_type (MONO_TYPE_I2);
6768 arg_types [0] = ret_type;
6769 arg_types [1] = LLVMInt32Type ();
6770 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
6771 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
6772 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
6773 ret_type = type_to_simd_type (MONO_TYPE_I4);
6774 arg_types [0] = ret_type;
6775 arg_types [1] = LLVMInt32Type ();
6776 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
6777 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
6778 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
6779 ret_type = type_to_simd_type (MONO_TYPE_I8);
6780 arg_types [0] = ret_type;
6781 arg_types [1] = LLVMInt32Type ();
6782 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
6783 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
6786 ret_type = LLVMInt32Type ();
6787 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
6788 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
6791 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
6794 /* Load/Store intrinsics */
6796 LLVMTypeRef arg_types [5];
6800 for (i = 1; i <= 8; i *= 2) {
6801 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
6802 arg_types [1] = LLVMInt32Type ();
6803 arg_types [2] = LLVMInt1Type ();
6804 arg_types [3] = LLVMInt32Type ();
6805 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
6806 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
6808 arg_types [0] = LLVMIntType (i * 8);
6809 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
6810 arg_types [2] = LLVMInt32Type ();
6811 arg_types [3] = LLVMInt1Type ();
6812 arg_types [4] = LLVMInt32Type ();
6813 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
6814 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
6820 add_types (MonoLLVMModule *lmodule)
6822 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
6826 mono_llvm_init (void)
6828 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
6832 init_jit_module (MonoDomain *domain)
6834 MonoJitDomainInfo *dinfo;
6835 MonoLLVMModule *module;
6838 dinfo = domain_jit_info (domain);
6839 if (dinfo->llvm_module)
6842 mono_loader_lock ();
6844 if (dinfo->llvm_module) {
6845 mono_loader_unlock ();
6849 module = g_new0 (MonoLLVMModule, 1);
6851 name = g_strdup_printf ("mono-%s", domain->friendly_name);
6852 module->module = LLVMModuleCreateWithName (name);
6854 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
6856 add_intrinsics (module->module);
6859 module->llvm_types = g_hash_table_new (NULL, NULL);
6861 mono_memory_barrier ();
6863 dinfo->llvm_module = module;
6865 mono_loader_unlock ();
6869 mono_llvm_cleanup (void)
6871 if (aot_module.module)
6872 LLVMDisposeModule (aot_module.module);
6874 if (aot_module.context)
6875 LLVMContextDispose (aot_module.context);
6879 mono_llvm_free_domain_info (MonoDomain *domain)
6881 MonoJitDomainInfo *info = domain_jit_info (domain);
6882 MonoLLVMModule *module = info->llvm_module;
6888 if (module->llvm_types)
6889 g_hash_table_destroy (module->llvm_types);
6891 mono_llvm_dispose_ee (module->mono_ee);
6893 if (module->bb_names) {
6894 for (i = 0; i < module->bb_names_len; ++i)
6895 g_free (module->bb_names [i]);
6896 g_free (module->bb_names);
6898 //LLVMDisposeModule (module->module);
6902 info->llvm_module = NULL;
6906 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
6908 MonoLLVMModule *lmodule = &aot_module;
6910 /* Delete previous module */
6911 if (lmodule->plt_entries)
6912 g_hash_table_destroy (lmodule->plt_entries);
6913 if (lmodule->module)
6914 LLVMDisposeModule (lmodule->module);
6916 memset (lmodule, 0, sizeof (aot_module));
6918 lmodule->module = LLVMModuleCreateWithName ("aot");
6919 lmodule->assembly = assembly;
6920 lmodule->global_prefix = g_strdup (global_prefix);
6921 lmodule->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
6922 lmodule->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
6923 lmodule->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
6924 lmodule->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
6925 lmodule->external_symbols = TRUE;
6926 lmodule->emit_dwarf = emit_dwarf;
6927 lmodule->static_link = static_link;
6928 lmodule->llvm_only = llvm_only;
6929 /* The first few entries are reserved */
6930 lmodule->max_got_offset = 16;
6931 lmodule->context = LLVMContextCreate ();
6934 add_intrinsics (lmodule->module);
6935 add_types (lmodule);
6936 emit_llvm_code_start (lmodule);
6940 * We couldn't compute the type of the LLVM global representing the got because
6941 * its size is only known after all the methods have been emitted. So create
6942 * a dummy variable, and replace all uses it with the real got variable when
6943 * its size is known in mono_llvm_emit_aot_module ().
6946 LLVMTypeRef got_type = LLVMArrayType (lmodule->ptr_type, 0);
6948 aot_module.got_var = LLVMAddGlobal (lmodule->module, got_type, "mono_dummy_got");
6949 LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
6952 /* Add initialization array */
6954 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
6956 aot_module.inited_var = LLVMAddGlobal (aot_module.module, inited_type, "mono_inited_tmp");
6957 LLVMSetInitializer (aot_module.inited_var, LLVMConstNull (inited_type));
6960 /* Add a dummy personality function */
6961 if (!use_debug_personality) {
6962 LLVMValueRef personality = LLVMAddFunction (lmodule->module, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
6963 LLVMSetLinkage (personality, LLVMExternalLinkage);
6964 mark_as_used (lmodule, personality);
6967 /* Add a reference to the c++ exception we throw/catch */
6969 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
6970 lmodule->sentinel_exception = LLVMAddGlobal (lmodule->module, exc, "_ZTIPi");
6971 LLVMSetLinkage (lmodule->sentinel_exception, LLVMExternalLinkage);
6972 mono_llvm_set_is_constant (lmodule->sentinel_exception);
6975 lmodule->llvm_types = g_hash_table_new (NULL, NULL);
6976 lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
6977 lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
6978 lmodule->method_to_lmethod = g_hash_table_new (NULL, NULL);
6979 lmodule->idx_to_lmethod = g_hash_table_new (NULL, NULL);
6980 lmodule->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
6984 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
6987 LLVMValueRef res, *vals;
6989 vals = g_new0 (LLVMValueRef, nvalues);
6990 for (i = 0; i < nvalues; ++i)
6991 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
6992 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
6998 * mono_llvm_emit_aot_file_info:
7000 * Emit the MonoAotFileInfo structure.
7001 * Same as emit_aot_file_info () in aot-compiler.c.
7004 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7006 MonoLLVMModule *lmodule = &aot_module;
7008 /* Save these for later */
7009 memcpy (&lmodule->aot_info, info, sizeof (MonoAotFileInfo));
7010 lmodule->has_jitted_code = has_jitted_code;
7014 * mono_llvm_emit_aot_data:
7016 * Emit the binary data DATA pointed to by symbol SYMBOL.
7019 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7021 MonoLLVMModule *lmodule = &aot_module;
7025 type = LLVMArrayType (LLVMInt8Type (), data_len);
7026 d = LLVMAddGlobal (lmodule->module, type, symbol);
7027 LLVMSetVisibility (d, LLVMHiddenVisibility);
7028 LLVMSetLinkage (d, LLVMInternalLinkage);
7029 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7030 mono_llvm_set_is_constant (d);
7033 /* Add a reference to a global defined in JITted code */
7035 AddJitGlobal (MonoLLVMModule *lmodule, LLVMTypeRef type, const char *name)
7040 s = g_strdup_printf ("%s%s", lmodule->global_prefix, name);
7041 v = LLVMAddGlobal (lmodule->module, LLVMInt8Type (), s);
7047 emit_aot_file_info (MonoLLVMModule *lmodule)
7049 LLVMTypeRef file_info_type;
7050 LLVMTypeRef *eltypes, eltype;
7051 LLVMValueRef info_var;
7052 LLVMValueRef *fields;
7053 int i, nfields, tindex;
7054 MonoAotFileInfo *info;
7056 info = &lmodule->aot_info;
7058 /* Create an LLVM type to represent MonoAotFileInfo */
7059 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 13 + 4;
7060 eltypes = g_new (LLVMTypeRef, nfields);
7062 eltypes [tindex ++] = LLVMInt32Type ();
7063 eltypes [tindex ++] = LLVMInt32Type ();
7065 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7066 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7068 for (i = 0; i < 13; ++i)
7069 eltypes [tindex ++] = LLVMInt32Type ();
7071 for (i = 0; i < 4; ++i)
7072 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7073 g_assert (tindex == nfields);
7074 file_info_type = LLVMStructCreateNamed (aot_module.context, "MonoAotFileInfo");
7075 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7077 info_var = LLVMAddGlobal (lmodule->module, file_info_type, "mono_aot_file_info");
7078 if (lmodule->static_link) {
7079 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7080 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7082 fields = g_new (LLVMValueRef, nfields);
7084 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7085 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7089 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7090 * for symbols defined in the .s file emitted by the aot compiler.
7092 eltype = eltypes [tindex];
7093 if (lmodule->llvm_only)
7094 fields [tindex ++] = LLVMConstNull (eltype);
7096 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_got");
7097 fields [tindex ++] = lmodule->got_var;
7098 /* llc defines this directly */
7099 if (!lmodule->llvm_only) {
7100 fields [tindex ++] = LLVMAddGlobal (lmodule->module, eltype, lmodule->eh_frame_symbol);
7101 fields [tindex ++] = LLVMConstNull (eltype);
7102 fields [tindex ++] = LLVMConstNull (eltype);
7104 fields [tindex ++] = LLVMConstNull (eltype);
7105 fields [tindex ++] = lmodule->get_method;
7106 fields [tindex ++] = lmodule->get_unbox_tramp;
7108 if (lmodule->has_jitted_code) {
7109 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_start");
7110 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "jit_code_end");
7112 fields [tindex ++] = LLVMConstNull (eltype);
7113 fields [tindex ++] = LLVMConstNull (eltype);
7115 if (!lmodule->llvm_only)
7116 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "method_addresses");
7118 fields [tindex ++] = LLVMConstNull (eltype);
7119 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "blob");
7120 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_name_table");
7121 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "class_info_offsets");
7122 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "method_info_offsets");
7123 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "ex_info_offsets");
7124 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_info_offsets");
7125 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "extra_method_table");
7126 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "got_info_offsets");
7127 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "llvm_got_info_offsets");
7128 /* Not needed (mem_end) */
7129 fields [tindex ++] = LLVMConstNull (eltype);
7130 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "image_table");
7131 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_guid");
7132 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "runtime_version");
7133 if (info->trampoline_size [0]) {
7134 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "specific_trampolines");
7135 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "static_rgctx_trampolines");
7136 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "imt_thunks");
7137 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "gsharedvt_arg_trampolines");
7139 fields [tindex ++] = LLVMConstNull (eltype);
7140 fields [tindex ++] = LLVMConstNull (eltype);
7141 fields [tindex ++] = LLVMConstNull (eltype);
7142 fields [tindex ++] = LLVMConstNull (eltype);
7144 if (lmodule->static_link)
7145 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "globals");
7147 fields [tindex ++] = LLVMConstNull (eltype);
7148 fields [tindex ++] = LLVMGetNamedGlobal (lmodule->module, "assembly_name");
7149 if (!lmodule->llvm_only) {
7150 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt");
7151 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "plt_end");
7152 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unwind_info");
7153 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines");
7154 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampolines_end");
7155 fields [tindex ++] = AddJitGlobal (lmodule, eltype, "unbox_trampoline_addresses");
7157 fields [tindex ++] = LLVMConstNull (eltype);
7158 fields [tindex ++] = LLVMConstNull (eltype);
7159 fields [tindex ++] = LLVMConstNull (eltype);
7160 fields [tindex ++] = LLVMConstNull (eltype);
7161 fields [tindex ++] = LLVMConstNull (eltype);
7162 fields [tindex ++] = LLVMConstNull (eltype);
7165 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7166 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7169 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7170 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7171 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7172 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7173 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7174 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7175 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7176 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7177 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7178 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7179 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7180 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7181 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7183 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7184 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7185 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7186 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7187 g_assert (tindex == nfields);
7189 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7191 if (lmodule->static_link) {
7195 s = g_strdup_printf ("mono_aot_module_%s_info", lmodule->assembly->aname.name);
7196 /* Get rid of characters which cannot occur in symbols */
7198 for (p = s; *p; ++p) {
7199 if (!(isalnum (*p) || *p == '_'))
7202 var = LLVMAddGlobal (lmodule->module, LLVMPointerType (LLVMInt8Type (), 0), s);
7204 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (lmodule->module, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7205 LLVMSetLinkage (var, LLVMExternalLinkage);
7210 * Emit the aot module into the LLVM bitcode file FILENAME.
7213 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7215 LLVMTypeRef got_type, inited_type;
7216 LLVMValueRef real_got, real_inited;
7217 MonoLLVMModule *module = &aot_module;
7219 emit_llvm_code_end (module);
7222 * Create the real got variable and replace all uses of the dummy variable with
7225 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
7226 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
7227 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7228 if (module->external_symbols) {
7229 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7230 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7232 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7234 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
7236 mark_as_used (&aot_module, real_got);
7238 /* Delete the dummy got so it doesn't become a global */
7239 LLVMDeleteGlobal (aot_module.got_var);
7240 aot_module.got_var = real_got;
7243 * Same for the init_var
7245 if (aot_module.llvm_only) {
7246 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7247 real_inited = LLVMAddGlobal (aot_module.module, inited_type, "mono_inited");
7248 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7249 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7250 mono_llvm_replace_uses_of (aot_module.inited_var, real_inited);
7251 LLVMDeleteGlobal (aot_module.inited_var);
7254 if (aot_module.llvm_only) {
7255 emit_get_method (&aot_module);
7256 emit_get_unbox_tramp (&aot_module);
7259 emit_llvm_used (&aot_module);
7260 emit_dbg_info (&aot_module, filename, cu_name);
7261 emit_aot_file_info (&aot_module);
7263 /* Replace PLT entries for directly callable methods with the methods themselves */
7265 GHashTableIter iter;
7267 LLVMValueRef callee;
7269 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
7270 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7271 if (mono_aot_is_direct_callable (ji)) {
7272 LLVMValueRef lmethod;
7274 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7275 /* The types might not match because the caller might pass an rgctx */
7276 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7277 mono_llvm_replace_uses_of (callee, lmethod);
7278 mono_aot_mark_unused_llvm_plt_entry (ji);
7288 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
7289 g_assert_not_reached ();
7294 LLVMWriteBitcodeToFile (aot_module.module, filename);
7299 md_string (const char *s)
7301 return LLVMMDString (s, strlen (s));
7304 /* Debugging support */
7307 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
7309 LLVMModuleRef module = lmodule->module;
7310 LLVMValueRef args [16], cu_args [16], cu, ver;
7312 char *build_info, *s, *dir;
7315 * This can only be enabled when LLVM code is emitted into a separate object
7316 * file, since the AOT compiler also emits dwarf info,
7317 * and the abbrev indexes will not be correct since llvm has added its own
7320 if (!lmodule->emit_dwarf)
7324 * Emit dwarf info in the form of LLVM metadata. There is some
7325 * out-of-date documentation at:
7326 * http://llvm.org/docs/SourceLevelDebugging.html
7327 * but most of this was gathered from the llvm and
7332 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
7333 /* CU name/compilation dir */
7334 dir = g_path_get_dirname (filename);
7335 args [0] = LLVMMDString (cu_name, strlen (cu_name));
7336 args [1] = LLVMMDString (dir, strlen (dir));
7337 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
7340 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
7342 build_info = mono_get_runtime_build_info ();
7343 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7344 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
7345 g_free (build_info);
7347 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7349 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7350 /* Runtime version */
7351 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7353 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7354 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7356 if (lmodule->subprogram_mds) {
7360 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
7361 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
7362 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
7363 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
7365 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7368 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7369 /* Imported modules */
7370 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7372 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7373 /* DebugEmissionKind = FullDebug */
7374 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7375 cu = LLVMMDNode (cu_args, n_cuargs);
7376 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
7378 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7379 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
7380 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
7381 ver = LLVMMDNode (args, 3);
7382 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
7384 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7385 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
7386 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7387 ver = LLVMMDNode (args, 3);
7388 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
7392 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
7394 MonoLLVMModule *module = ctx->lmodule;
7395 MonoDebugMethodInfo *minfo = ctx->minfo;
7396 char *source_file, *dir, *filename;
7397 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
7398 MonoSymSeqPoint *sym_seq_points;
7404 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
7406 source_file = g_strdup ("<unknown>");
7407 dir = g_path_get_dirname (source_file);
7408 filename = g_path_get_basename (source_file);
7410 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
7411 args [0] = md_string (filename);
7412 args [1] = md_string (dir);
7413 ctx_args [1] = LLVMMDNode (args, 2);
7414 ctx_md = LLVMMDNode (ctx_args, 2);
7416 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
7417 type_args [1] = NULL;
7418 type_args [2] = NULL;
7419 type_args [3] = LLVMMDString ("", 0);
7420 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7421 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7422 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7423 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7424 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7425 type_args [9] = NULL;
7426 type_args [10] = NULL;
7427 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7428 type_args [12] = NULL;
7429 type_args [13] = NULL;
7430 type_args [14] = NULL;
7431 type_md = LLVMMDNode (type_args, 14);
7433 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
7434 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
7435 /* Source directory + file pair */
7436 args [0] = md_string (filename);
7437 args [1] = md_string (dir);
7438 md_args [1] = LLVMMDNode (args ,2);
7439 md_args [2] = ctx_md;
7440 md_args [3] = md_string (cfg->method->name);
7441 md_args [4] = md_string (name);
7442 md_args [5] = md_string (name);
7445 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
7447 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7449 md_args [7] = type_md;
7451 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
7453 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
7455 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7456 /* Index into a virtual function */
7457 md_args [11] = NULL;
7458 md_args [12] = NULL;
7460 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
7462 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
7463 /* Pointer to LLVM function */
7464 md_args [15] = method;
7465 /* Function template parameter */
7466 md_args [16] = NULL;
7467 /* Function declaration descriptor */
7468 md_args [17] = NULL;
7469 /* List of function variables */
7470 md_args [18] = LLVMMDNode (args, 0);
7472 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7473 md = LLVMMDNode (md_args, 20);
7475 if (!module->subprogram_mds)
7476 module->subprogram_mds = g_ptr_array_new ();
7477 g_ptr_array_add (module->subprogram_mds, md);
7481 g_free (source_file);
7482 g_free (sym_seq_points);
7488 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
7490 MonoCompile *cfg = ctx->cfg;
7492 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
7493 MonoDebugSourceLocation *loc;
7494 LLVMValueRef loc_md, md_args [16];
7497 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
7501 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
7502 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
7503 md_args [nmd_args ++] = ctx->dbg_md;
7504 md_args [nmd_args ++] = NULL;
7505 loc_md = LLVMMDNode (md_args, nmd_args);
7506 LLVMSetCurrentDebugLocation (builder, loc_md);
7507 mono_debug_symfile_free_location (loc);
7513 static gboolean show_native_addresses = TRUE;
7515 static gboolean show_native_addresses = FALSE;
7518 static _Unwind_Reason_Code
7519 build_stack_trace (struct _Unwind_Context *frame_ctx, void *state)
7521 MonoDomain *domain = mono_domain_get ();
7522 uintptr_t ip = _Unwind_GetIP (frame_ctx);
7524 if (show_native_addresses || mono_jit_info_table_find (domain, (char*)ip)) {
7525 GList **trace_ips = (GList **)state;
7526 *trace_ips = g_list_prepend (*trace_ips, (gpointer)ip);
7529 return _URC_NO_REASON;
7533 throw_exception (MonoObject *ex, gboolean rethrow)
7535 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7536 MonoException *mono_ex;
7538 if (!mono_object_isinst (ex, mono_defaults.exception_class))
7539 mono_ex = mono_get_exception_runtime_wrapped (ex);
7541 mono_ex = (MonoException*)ex;
7544 jit_tls->thrown_exc = mono_gchandle_new ((MonoObject*)mono_ex, FALSE);
7547 GList *l, *ips = NULL;
7550 // FIXME: Move this to mini-exceptions.c
7551 _Unwind_Backtrace (build_stack_trace, &ips);
7552 /* The list contains gshared info-ip pairs */
7554 ips = g_list_reverse (ips);
7555 for (l = ips; l; l = l->next) {
7557 trace = g_list_append (trace, l->data);
7558 trace = g_list_append (trace, NULL);
7560 MONO_OBJECT_SETREF (mono_ex, trace_ips, mono_glist_to_array (trace, mono_defaults.int_class));
7562 g_list_free (trace);
7565 mono_llvm_cpp_throw_exception ();
7569 mono_llvm_throw_exception (MonoObject *ex)
7571 throw_exception (ex, FALSE);
7575 mono_llvm_rethrow_exception (MonoObject *ex)
7577 throw_exception (ex, TRUE);
7581 mono_llvm_raise_exception (MonoException *e)
7583 mono_llvm_throw_exception ((MonoObject*)e);
7587 mono_llvm_throw_corlib_exception (guint32 ex_token_index)
7589 guint32 ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index;
7592 ex = mono_exception_from_token (mono_defaults.exception_class->image, ex_token);
7594 mono_llvm_throw_exception ((MonoObject*)ex);
7598 * mono_llvm_resume_exception:
7600 * Resume exception propagation.
7603 mono_llvm_resume_exception (void)
7605 mono_llvm_cpp_throw_exception ();
7609 * mono_llvm_load_exception:
7611 * Return the currently thrown exception.
7614 mono_llvm_load_exception (void)
7616 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7618 MonoException *mono_ex = (MonoException*)mono_gchandle_get_target (jit_tls->thrown_exc);
7619 g_assert (mono_ex->trace_ips);
7621 GList *trace_ips = NULL;
7622 gpointer ip = __builtin_return_address (0);
7624 size_t upper = mono_array_length (mono_ex->trace_ips);
7626 for (int i = 0; i < upper; i++) {
7627 gpointer curr_ip = mono_array_get (mono_ex->trace_ips, gpointer, i);
7628 trace_ips = g_list_prepend (trace_ips, curr_ip);
7634 // FIXME: Does this work correctly for rethrows?
7635 // We may be discarding useful information
7636 // when this gets GC'ed
7637 MONO_OBJECT_SETREF (mono_ex, trace_ips, mono_glist_to_array (trace_ips, mono_defaults.int_class));
7638 g_list_free (trace_ips);
7641 //MONO_OBJECT_SETREF (mono_ex, stack_trace, ves_icall_System_Exception_get_trace (mono_ex));
7643 return &mono_ex->object;
7647 * mono_llvm_clear_exception:
7649 * Mark the currently thrown exception as handled.
7652 mono_llvm_clear_exception (void)
7654 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7655 mono_gchandle_free (jit_tls->thrown_exc);
7656 jit_tls->thrown_exc = 0;
7658 mono_memory_barrier ();
7662 * mono_llvm_match_exception:
7664 * Return the innermost clause containing REGION_START-REGION_END which can handle
7665 * the current exception.
7668 mono_llvm_match_exception (MonoJitInfo *jinfo, guint32 region_start, guint32 region_end)
7670 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7674 g_assert (jit_tls->thrown_exc);
7675 exc = mono_gchandle_get_target (jit_tls->thrown_exc);
7676 for (int i = 0; i < jinfo->num_clauses; i++) {
7677 MonoJitExceptionInfo *ei = &jinfo->clauses [i];
7679 if (! (ei->try_offset == region_start && ei->try_offset + ei->try_len == region_end) )
7682 // FIXME: Handle edge cases handled in get_exception_catch_class
7683 if (ei->flags == MONO_EXCEPTION_CLAUSE_NONE && mono_object_isinst (exc, ei->data.catch_class)) {
7684 index = ei->clause_index;
7686 } else if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
7687 g_assert_not_reached ();
7695 default_mono_llvm_unhandled_exception (void)
7697 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7698 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
7700 mono_unhandled_exception (target);
7701 exit (mono_environment_exitcode_get ());
7706 - Emit LLVM IR from the mono IR using the LLVM C API.
7707 - The original arch specific code remains, so we can fall back to it if we run
7708 into something we can't handle.
7712 A partial list of issues:
7713 - Handling of opcodes which can throw exceptions.
7715 In the mono JIT, these are implemented using code like this:
7722 push throw_pos - method
7723 call <exception trampoline>
7725 The problematic part is push throw_pos - method, which cannot be represented
7726 in the LLVM IR, since it does not support label values.
7727 -> this can be implemented in AOT mode using inline asm + labels, but cannot
7728 be implemented in JIT mode ?
7729 -> a possible but slower implementation would use the normal exception
7730 throwing code but it would need to control the placement of the throw code
7731 (it needs to be exactly after the compare+branch).
7732 -> perhaps add a PC offset intrinsics ?
7734 - efficient implementation of .ovf opcodes.
7736 These are currently implemented as:
7737 <ins which sets the condition codes>
7740 Some overflow opcodes are now supported by LLVM SVN.
7742 - exception handling, unwinding.
7743 - SSA is disabled for methods with exception handlers
7744 - How to obtain unwind info for LLVM compiled methods ?
7745 -> this is now solved by converting the unwind info generated by LLVM
7747 - LLVM uses the c++ exception handling framework, while we use our home grown
7748 code, and couldn't use the c++ one:
7749 - its not supported under VC++, other exotic platforms.
7750 - it might be impossible to support filter clauses with it.
7754 The trampolines need a predictable call sequence, since they need to disasm
7755 the calling code to obtain register numbers / offsets.
7757 LLVM currently generates this code in non-JIT mode:
7758 mov -0x98(%rax),%eax
7760 Here, the vtable pointer is lost.
7761 -> solution: use one vtable trampoline per class.
7763 - passing/receiving the IMT pointer/RGCTX.
7764 -> solution: pass them as normal arguments ?
7768 LLVM does not allow the specification of argument registers etc. This means
7769 that all calls are made according to the platform ABI.
7771 - passing/receiving vtypes.
7773 Vtypes passed/received in registers are handled by the front end by using
7774 a signature with scalar arguments, and loading the parts of the vtype into those
7777 Vtypes passed on the stack are handled using the 'byval' attribute.
7781 Supported though alloca, we need to emit the load/store code.
7785 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
7786 typed registers, so we have to keep track of the precise LLVM type of each vreg.
7787 This is made easier because the IR is already in SSA form.
7788 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
7789 types are frequently used incorrectly.
7794 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
7795 it with the file containing the methods emitted by the JIT and the AOT data
7799 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
7800 * - each bblock should end with a branch
7801 * - setting the return value, making cfg->ret non-volatile
7802 * - avoid some transformations in the JIT which make it harder for us to generate
7804 * - use pointer types to help optimizations.