2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 GHashTable *llvm_types;
51 const char *got_symbol;
52 GHashTable *plt_entries;
53 GHashTable *plt_entries_ji;
54 GHashTable *method_to_lmethod;
59 GPtrArray *subprogram_mds;
61 LLVMExecutionEngineRef ee;
62 gboolean external_symbols;
68 * Information associated by the backend with mono basic blocks.
71 LLVMBasicBlockRef bblock, end_bblock;
72 LLVMValueRef finally_ind;
73 gboolean added, invoke_target;
75 * If this bblock is the start of a finally clause, this is a list of bblocks it
76 * needs to branch to in ENDFINALLY.
78 GSList *call_handler_return_bbs;
80 * If this bblock is the start of a finally clause, this is the bblock that
81 * CALL_HANDLER needs to branch to.
83 LLVMBasicBlockRef call_handler_target_bb;
84 /* The list of switch statements generated by ENDFINALLY instructions */
85 GSList *endfinally_switch_ins_list;
90 * Structure containing emit state
95 /* Maps method names to the corresponding LLVMValueRef */
96 GHashTable *emitted_method_decls;
100 MonoLLVMModule *lmodule;
101 LLVMModuleRef module;
103 int sindex, default_index, ex_index;
104 LLVMBuilderRef builder;
105 LLVMValueRef *values, *addresses;
106 MonoType **vreg_cli_types;
108 MonoMethodSignature *sig;
110 GHashTable *region_to_handler;
111 GHashTable *clause_to_handler;
112 LLVMBuilderRef alloca_builder;
113 LLVMValueRef last_alloca;
114 LLVMValueRef rgctx_arg;
115 LLVMTypeRef *vreg_types;
117 gboolean *unreachable;
119 LLVMValueRef imt_rgctx_loc;
120 GHashTable *llvm_types;
122 MonoDebugMethodInfo *minfo;
124 /* For every clause, the clauses it is nested in */
132 MonoBasicBlock *in_bb;
137 * Instruction metadata
138 * This is the same as ins_info, but LREG != IREG.
146 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
147 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
154 /* keep in sync with the enum in mini.h */
157 #include "mini-ops.h"
162 #if SIZEOF_VOID_P == 4
163 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
165 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
168 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
171 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
173 #define TRACE_FAILURE(msg)
177 #define IS_TARGET_X86 1
179 #define IS_TARGET_X86 0
183 #define IS_TARGET_AMD64 1
185 #define IS_TARGET_AMD64 0
188 #define LLVM_FAILURE(ctx, reason) do { \
189 TRACE_FAILURE (reason); \
190 (ctx)->cfg->exception_message = g_strdup (reason); \
191 (ctx)->cfg->disable_llvm = TRUE; \
195 #define CHECK_FAILURE(ctx) do { \
196 if ((ctx)->cfg->disable_llvm) \
200 static LLVMIntPredicate cond_to_llvm_cond [] = {
213 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
226 static MonoNativeTlsKey current_cfg_tls_id;
228 static MonoLLVMModule aot_module;
229 static int memset_param_count, memcpy_param_count;
230 static const char *memset_func_name;
231 static const char *memcpy_func_name;
233 static void init_jit_module (MonoDomain *domain);
235 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
236 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
237 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
242 * The LLVM type with width == sizeof (gpointer)
247 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
253 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
259 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
265 * Return the size of the LLVM representation of the vtype T.
268 get_vtype_size (MonoType *t)
272 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
274 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
281 * simd_class_to_llvm_type:
283 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
286 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
288 if (!strcmp (klass->name, "Vector2d")) {
289 return LLVMVectorType (LLVMDoubleType (), 2);
290 } else if (!strcmp (klass->name, "Vector2l")) {
291 return LLVMVectorType (LLVMInt64Type (), 2);
292 } else if (!strcmp (klass->name, "Vector2ul")) {
293 return LLVMVectorType (LLVMInt64Type (), 2);
294 } else if (!strcmp (klass->name, "Vector4i")) {
295 return LLVMVectorType (LLVMInt32Type (), 4);
296 } else if (!strcmp (klass->name, "Vector4ui")) {
297 return LLVMVectorType (LLVMInt32Type (), 4);
298 } else if (!strcmp (klass->name, "Vector4f")) {
299 return LLVMVectorType (LLVMFloatType (), 4);
300 } else if (!strcmp (klass->name, "Vector8s")) {
301 return LLVMVectorType (LLVMInt16Type (), 8);
302 } else if (!strcmp (klass->name, "Vector8us")) {
303 return LLVMVectorType (LLVMInt16Type (), 8);
304 } else if (!strcmp (klass->name, "Vector16sb")) {
305 return LLVMVectorType (LLVMInt8Type (), 16);
306 } else if (!strcmp (klass->name, "Vector16b")) {
307 return LLVMVectorType (LLVMInt8Type (), 16);
309 printf ("%s\n", klass->name);
315 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
316 static inline G_GNUC_UNUSED LLVMTypeRef
317 type_to_simd_type (int type)
321 return LLVMVectorType (LLVMInt8Type (), 16);
323 return LLVMVectorType (LLVMInt16Type (), 8);
325 return LLVMVectorType (LLVMInt32Type (), 4);
327 return LLVMVectorType (LLVMInt64Type (), 2);
329 return LLVMVectorType (LLVMDoubleType (), 2);
331 return LLVMVectorType (LLVMFloatType (), 4);
333 g_assert_not_reached ();
339 create_llvm_type_for_type (MonoClass *klass)
341 int i, size, nfields, esize;
342 LLVMTypeRef *eltypes;
347 t = &klass->byval_arg;
349 if (mini_type_is_hfa (t, &nfields, &esize)) {
351 * This is needed on arm64 where HFAs are returned in
355 eltypes = g_new (LLVMTypeRef, size);
356 for (i = 0; i < size; ++i)
357 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
359 size = get_vtype_size (t);
361 eltypes = g_new (LLVMTypeRef, size);
362 for (i = 0; i < size; ++i)
363 eltypes [i] = LLVMInt8Type ();
366 name = mono_type_full_name (&klass->byval_arg);
367 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
368 LLVMStructSetBody (ltype, eltypes, size, FALSE);
378 * Return the LLVM type corresponding to T.
381 type_to_llvm_type (EmitContext *ctx, MonoType *t)
384 return LLVMPointerType (LLVMInt8Type (), 0);
386 t = mini_get_underlying_type (ctx->cfg, t);
389 return LLVMVoidType ();
391 return LLVMInt8Type ();
393 return LLVMInt16Type ();
395 return LLVMInt32Type ();
397 return LLVMInt8Type ();
399 return LLVMInt16Type ();
401 return LLVMInt32Type ();
402 case MONO_TYPE_BOOLEAN:
403 return LLVMInt8Type ();
406 return LLVMInt64Type ();
408 return LLVMInt16Type ();
410 return LLVMFloatType ();
412 return LLVMDoubleType ();
415 return IntPtrType ();
416 case MONO_TYPE_OBJECT:
417 case MONO_TYPE_CLASS:
418 case MONO_TYPE_ARRAY:
419 case MONO_TYPE_SZARRAY:
420 case MONO_TYPE_STRING:
422 return ObjRefType ();
425 /* Because of generic sharing */
426 return ObjRefType ();
427 case MONO_TYPE_GENERICINST:
428 if (!mono_type_generic_inst_is_valuetype (t))
429 return ObjRefType ();
431 case MONO_TYPE_VALUETYPE:
432 case MONO_TYPE_TYPEDBYREF: {
436 klass = mono_class_from_mono_type (t);
438 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
439 return simd_class_to_llvm_type (ctx, klass);
442 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
444 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
446 ltype = create_llvm_type_for_type (klass);
447 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
453 printf ("X: %d\n", t->type);
454 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
455 ctx->cfg->disable_llvm = TRUE;
463 * Return whenever T is an unsigned int type.
466 type_is_unsigned (EmitContext *ctx, MonoType *t)
483 * type_to_llvm_arg_type:
485 * Same as type_to_llvm_type, but treat i8/i16 as i32.
488 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
490 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
493 * This works on all abis except arm64/ios which passes multiple
494 * arguments in one stack slot.
497 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
499 * LLVM generates code which only sets the lower bits, while JITted
500 * code expects all the bits to be set.
502 ptype = LLVMInt32Type ();
510 * llvm_type_to_stack_type:
512 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
515 static G_GNUC_UNUSED LLVMTypeRef
516 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
520 if (type == LLVMInt8Type ())
521 return LLVMInt32Type ();
522 else if (type == LLVMInt16Type ())
523 return LLVMInt32Type ();
524 else if (!cfg->r4fp && type == LLVMFloatType ())
525 return LLVMDoubleType ();
531 * regtype_to_llvm_type:
533 * Return the LLVM type corresponding to the regtype C used in instruction
537 regtype_to_llvm_type (char c)
541 return LLVMInt32Type ();
543 return LLVMInt64Type ();
545 return LLVMDoubleType ();
554 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
557 op_to_llvm_type (int opcode)
562 return LLVMInt8Type ();
565 return LLVMInt8Type ();
568 return LLVMInt16Type ();
571 return LLVMInt16Type ();
574 return LLVMInt32Type ();
577 return LLVMInt32Type ();
579 return LLVMInt64Type ();
581 return LLVMFloatType ();
583 return LLVMDoubleType ();
585 return LLVMInt64Type ();
587 return LLVMInt32Type ();
589 return LLVMInt64Type ();
594 return LLVMInt8Type ();
599 return LLVMInt16Type ();
602 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
609 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 printf ("%s\n", mono_inst_name (opcode));
619 g_assert_not_reached ();
625 * load_store_to_llvm_type:
627 * Return the size/sign/zero extension corresponding to the load/store opcode
631 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
637 case OP_LOADI1_MEMBASE:
638 case OP_STOREI1_MEMBASE_REG:
639 case OP_STOREI1_MEMBASE_IMM:
640 case OP_ATOMIC_LOAD_I1:
641 case OP_ATOMIC_STORE_I1:
644 return LLVMInt8Type ();
645 case OP_LOADU1_MEMBASE:
647 case OP_ATOMIC_LOAD_U1:
648 case OP_ATOMIC_STORE_U1:
651 return LLVMInt8Type ();
652 case OP_LOADI2_MEMBASE:
653 case OP_STOREI2_MEMBASE_REG:
654 case OP_STOREI2_MEMBASE_IMM:
655 case OP_ATOMIC_LOAD_I2:
656 case OP_ATOMIC_STORE_I2:
659 return LLVMInt16Type ();
660 case OP_LOADU2_MEMBASE:
662 case OP_ATOMIC_LOAD_U2:
663 case OP_ATOMIC_STORE_U2:
666 return LLVMInt16Type ();
667 case OP_LOADI4_MEMBASE:
668 case OP_LOADU4_MEMBASE:
671 case OP_STOREI4_MEMBASE_REG:
672 case OP_STOREI4_MEMBASE_IMM:
673 case OP_ATOMIC_LOAD_I4:
674 case OP_ATOMIC_STORE_I4:
675 case OP_ATOMIC_LOAD_U4:
676 case OP_ATOMIC_STORE_U4:
678 return LLVMInt32Type ();
679 case OP_LOADI8_MEMBASE:
681 case OP_STOREI8_MEMBASE_REG:
682 case OP_STOREI8_MEMBASE_IMM:
683 case OP_ATOMIC_LOAD_I8:
684 case OP_ATOMIC_STORE_I8:
685 case OP_ATOMIC_LOAD_U8:
686 case OP_ATOMIC_STORE_U8:
688 return LLVMInt64Type ();
689 case OP_LOADR4_MEMBASE:
690 case OP_STORER4_MEMBASE_REG:
691 case OP_ATOMIC_LOAD_R4:
692 case OP_ATOMIC_STORE_R4:
694 return LLVMFloatType ();
695 case OP_LOADR8_MEMBASE:
696 case OP_STORER8_MEMBASE_REG:
697 case OP_ATOMIC_LOAD_R8:
698 case OP_ATOMIC_STORE_R8:
700 return LLVMDoubleType ();
701 case OP_LOAD_MEMBASE:
703 case OP_STORE_MEMBASE_REG:
704 case OP_STORE_MEMBASE_IMM:
705 *size = sizeof (gpointer);
706 return IntPtrType ();
708 g_assert_not_reached ();
716 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
719 ovf_op_to_intrins (int opcode)
723 return "llvm.sadd.with.overflow.i32";
725 return "llvm.uadd.with.overflow.i32";
727 return "llvm.ssub.with.overflow.i32";
729 return "llvm.usub.with.overflow.i32";
731 return "llvm.smul.with.overflow.i32";
733 return "llvm.umul.with.overflow.i32";
735 return "llvm.sadd.with.overflow.i64";
737 return "llvm.uadd.with.overflow.i64";
739 return "llvm.ssub.with.overflow.i64";
741 return "llvm.usub.with.overflow.i64";
743 return "llvm.smul.with.overflow.i64";
745 return "llvm.umul.with.overflow.i64";
747 g_assert_not_reached ();
753 simd_op_to_intrins (int opcode)
756 #if defined(TARGET_X86) || defined(TARGET_AMD64)
758 return "llvm.x86.sse2.min.pd";
760 return "llvm.x86.sse.min.ps";
762 return "llvm.x86.sse41.pminud";
764 return "llvm.x86.sse41.pminuw";
766 return "llvm.x86.sse2.pminu.b";
768 return "llvm.x86.sse2.pmins.w";
770 return "llvm.x86.sse2.max.pd";
772 return "llvm.x86.sse.max.ps";
774 return "llvm.x86.sse3.hadd.pd";
776 return "llvm.x86.sse3.hadd.ps";
778 return "llvm.x86.sse3.hsub.pd";
780 return "llvm.x86.sse3.hsub.ps";
782 return "llvm.x86.sse41.pmaxud";
784 return "llvm.x86.sse41.pmaxuw";
786 return "llvm.x86.sse2.pmaxu.b";
788 return "llvm.x86.sse3.addsub.ps";
790 return "llvm.x86.sse3.addsub.pd";
791 case OP_EXTRACT_MASK:
792 return "llvm.x86.sse2.pmovmskb.128";
795 return "llvm.x86.sse2.psrli.w";
798 return "llvm.x86.sse2.psrli.d";
801 return "llvm.x86.sse2.psrli.q";
804 return "llvm.x86.sse2.pslli.w";
807 return "llvm.x86.sse2.pslli.d";
810 return "llvm.x86.sse2.pslli.q";
813 return "llvm.x86.sse2.psrai.w";
816 return "llvm.x86.sse2.psrai.d";
818 return "llvm.x86.sse2.padds.b";
820 return "llvm.x86.sse2.padds.w";
822 return "llvm.x86.sse2.psubs.b";
824 return "llvm.x86.sse2.psubs.w";
825 case OP_PADDB_SAT_UN:
826 return "llvm.x86.sse2.paddus.b";
827 case OP_PADDW_SAT_UN:
828 return "llvm.x86.sse2.paddus.w";
829 case OP_PSUBB_SAT_UN:
830 return "llvm.x86.sse2.psubus.b";
831 case OP_PSUBW_SAT_UN:
832 return "llvm.x86.sse2.psubus.w";
834 return "llvm.x86.sse2.pavg.b";
836 return "llvm.x86.sse2.pavg.w";
838 return "llvm.x86.sse.sqrt.ps";
840 return "llvm.x86.sse2.sqrt.pd";
842 return "llvm.x86.sse.rsqrt.ps";
844 return "llvm.x86.sse.rcp.ps";
846 return "llvm.x86.sse2.cvtdq2pd";
848 return "llvm.x86.sse2.cvtdq2ps";
850 return "llvm.x86.sse2.cvtpd2dq";
852 return "llvm.x86.sse2.cvtps2dq";
854 return "llvm.x86.sse2.cvtpd2ps";
856 return "llvm.x86.sse2.cvtps2pd";
858 return "llvm.x86.sse2.cvttpd2dq";
860 return "llvm.x86.sse2.cvttps2dq";
862 return "llvm.x86.sse.cmp.ps";
864 return "llvm.x86.sse2.cmp.pd";
866 return "llvm.x86.sse2.packsswb.128";
868 return "llvm.x86.sse2.packssdw.128";
870 return "llvm.x86.sse2.packuswb.128";
872 return "llvm.x86.sse41.packusdw";
874 return "llvm.x86.sse2.pmulh.w";
875 case OP_PMULW_HIGH_UN:
876 return "llvm.x86.sse2.pmulhu.w";
879 g_assert_not_reached ();
885 simd_op_to_llvm_type (int opcode)
887 #if defined(TARGET_X86) || defined(TARGET_AMD64)
891 return type_to_simd_type (MONO_TYPE_R8);
894 return type_to_simd_type (MONO_TYPE_I8);
897 return type_to_simd_type (MONO_TYPE_I4);
902 return type_to_simd_type (MONO_TYPE_I2);
906 return type_to_simd_type (MONO_TYPE_I1);
908 return type_to_simd_type (MONO_TYPE_R4);
911 return type_to_simd_type (MONO_TYPE_I4);
915 return type_to_simd_type (MONO_TYPE_R8);
919 return type_to_simd_type (MONO_TYPE_R4);
920 case OP_EXTRACT_MASK:
921 return type_to_simd_type (MONO_TYPE_I1);
927 return type_to_simd_type (MONO_TYPE_R4);
930 return type_to_simd_type (MONO_TYPE_R8);
932 g_assert_not_reached ();
943 * Return the LLVM basic block corresponding to BB.
945 static LLVMBasicBlockRef
946 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
948 char bb_name_buf [128];
951 if (ctx->bblocks [bb->block_num].bblock == NULL) {
952 if (bb->flags & BB_EXCEPTION_HANDLER) {
953 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
954 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
955 bb_name = bb_name_buf;
956 } else if (bb->block_num < 256) {
957 if (!ctx->lmodule->bb_names) {
958 ctx->lmodule->bb_names_len = 256;
959 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
961 if (!ctx->lmodule->bb_names [bb->block_num]) {
964 n = g_strdup_printf ("BB%d", bb->block_num);
965 mono_memory_barrier ();
966 ctx->lmodule->bb_names [bb->block_num] = n;
968 bb_name = ctx->lmodule->bb_names [bb->block_num];
970 sprintf (bb_name_buf, "BB%d", bb->block_num);
971 bb_name = bb_name_buf;
974 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
975 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
978 return ctx->bblocks [bb->block_num].bblock;
984 * Return the last LLVM bblock corresponding to BB.
985 * This might not be equal to the bb returned by get_bb () since we need to generate
986 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
988 static LLVMBasicBlockRef
989 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
992 return ctx->bblocks [bb->block_num].end_bblock;
995 static LLVMBasicBlockRef
996 gen_bb (EmitContext *ctx, const char *prefix)
1000 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1001 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1007 * Return the target of the patch identified by TYPE and TARGET.
1010 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1014 memset (&ji, 0, sizeof (ji));
1016 ji.data.target = target;
1018 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1024 * Emit code to convert the LLVM value V to DTYPE.
1027 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1029 LLVMTypeRef stype = LLVMTypeOf (v);
1031 if (stype != dtype) {
1032 gboolean ext = FALSE;
1035 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1037 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1039 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1043 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1045 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1046 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1049 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1050 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1051 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1052 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1053 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1054 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1055 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1056 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1058 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1059 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1060 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1061 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1062 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1063 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1065 if (mono_arch_is_soft_float ()) {
1066 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1067 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1068 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1069 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1072 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1073 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1076 LLVMDumpValue (LLVMConstNull (dtype));
1077 g_assert_not_reached ();
1085 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1087 return convert_full (ctx, v, dtype, FALSE);
1091 * emit_volatile_load:
1093 * If vreg is volatile, emit a load from its address.
1096 emit_volatile_load (EmitContext *ctx, int vreg)
1100 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1101 t = ctx->vreg_cli_types [vreg];
1102 if (t && !t->byref) {
1104 * Might have to zero extend since llvm doesn't have
1107 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1108 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1109 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1110 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1111 else if (t->type == MONO_TYPE_U8)
1112 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1119 * emit_volatile_store:
1121 * If VREG is volatile, emit a store from its value to its address.
1124 emit_volatile_store (EmitContext *ctx, int vreg)
1126 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1128 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1129 g_assert (ctx->addresses [vreg]);
1130 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1136 * Maps parameter indexes in the original signature to parameter indexes
1137 * in the LLVM signature.
1140 /* The indexes of various special arguments in the LLVM signature */
1141 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1145 * sig_to_llvm_sig_full:
1147 * Return the LLVM signature corresponding to the mono signature SIG using the
1148 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1151 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1154 LLVMTypeRef ret_type;
1155 LLVMTypeRef *param_types = NULL;
1157 int i, j, pindex, vret_arg_pindex = 0;
1159 gboolean vretaddr = FALSE;
1163 memset (sinfo, 0, sizeof (LLVMSigInfo));
1165 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1166 ret_type = type_to_llvm_type (ctx, rtype);
1167 CHECK_FAILURE (ctx);
1170 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1171 /* LLVM models this by returning an aggregate value */
1172 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1173 LLVMTypeRef members [2];
1175 members [0] = IntPtrType ();
1176 ret_type = LLVMStructType (members, 1, FALSE);
1178 g_assert_not_reached ();
1180 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1181 /* Vtype returned normally by val */
1182 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1183 /* Vtype returned as a fp struct */
1184 LLVMTypeRef members [16];
1186 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1187 for (i = 0; i < cinfo->ret.nslots; ++i)
1188 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1189 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1190 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1191 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1193 ret_type = LLVMVoidType ();
1197 pindexes = g_new0 (int, sig->param_count);
1198 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1200 if (cinfo && cinfo->rgctx_arg) {
1202 sinfo->rgctx_arg_pindex = pindex;
1203 param_types [pindex] = ctx->lmodule->ptr_type;
1206 if (cinfo && cinfo->imt_arg) {
1208 sinfo->imt_arg_pindex = pindex;
1209 param_types [pindex] = ctx->lmodule->ptr_type;
1213 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1214 vret_arg_pindex = pindex;
1215 if (cinfo->vret_arg_index == 1) {
1216 /* Add the slots consumed by the first argument */
1217 LLVMArgInfo *ainfo = &cinfo->args [0];
1218 switch (ainfo->storage) {
1219 case LLVMArgVtypeInReg:
1220 for (j = 0; j < 2; ++j) {
1221 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1231 sinfo->vret_arg_pindex = vret_arg_pindex;
1234 if (vretaddr && vret_arg_pindex == pindex)
1235 param_types [pindex ++] = IntPtrType ();
1238 sinfo->this_arg_pindex = pindex;
1239 param_types [pindex ++] = ThisType ();
1241 if (vretaddr && vret_arg_pindex == pindex)
1242 param_types [pindex ++] = IntPtrType ();
1243 for (i = 0; i < sig->param_count; ++i) {
1244 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1246 if (vretaddr && vret_arg_pindex == pindex)
1247 param_types [pindex ++] = IntPtrType ();
1248 pindexes [i] = pindex;
1251 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1255 switch (ainfo->storage) {
1256 case LLVMArgVtypeInReg:
1257 for (j = 0; j < 2; ++j) {
1258 switch (ainfo->pair_storage [j]) {
1260 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1265 g_assert_not_reached ();
1269 case LLVMArgVtypeByVal:
1270 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1271 CHECK_FAILURE (ctx);
1272 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1275 case LLVMArgAsIArgs:
1276 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1279 case LLVMArgAsFpArgs: {
1282 for (j = 0; j < ainfo->nslots; ++j)
1283 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1284 pindex += ainfo->nslots;
1288 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1292 if (vretaddr && vret_arg_pindex == pindex)
1293 param_types [pindex ++] = IntPtrType ();
1295 CHECK_FAILURE (ctx);
1297 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1298 g_free (param_types);
1301 sinfo->pindexes = pindexes;
1309 g_free (param_types);
1315 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1317 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1321 * LLVMFunctionType1:
1323 * Create an LLVM function type from the arguments.
1325 static G_GNUC_UNUSED LLVMTypeRef
1326 LLVMFunctionType1(LLVMTypeRef ReturnType,
1327 LLVMTypeRef ParamType1,
1330 LLVMTypeRef param_types [1];
1332 param_types [0] = ParamType1;
1334 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1338 * LLVMFunctionType2:
1340 * Create an LLVM function type from the arguments.
1342 static G_GNUC_UNUSED LLVMTypeRef
1343 LLVMFunctionType2(LLVMTypeRef ReturnType,
1344 LLVMTypeRef ParamType1,
1345 LLVMTypeRef ParamType2,
1348 LLVMTypeRef param_types [2];
1350 param_types [0] = ParamType1;
1351 param_types [1] = ParamType2;
1353 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1357 * LLVMFunctionType3:
1359 * Create an LLVM function type from the arguments.
1361 static G_GNUC_UNUSED LLVMTypeRef
1362 LLVMFunctionType3(LLVMTypeRef ReturnType,
1363 LLVMTypeRef ParamType1,
1364 LLVMTypeRef ParamType2,
1365 LLVMTypeRef ParamType3,
1368 LLVMTypeRef param_types [3];
1370 param_types [0] = ParamType1;
1371 param_types [1] = ParamType2;
1372 param_types [2] = ParamType3;
1374 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1380 * Create an LLVM builder and remember it so it can be freed later.
1382 static LLVMBuilderRef
1383 create_builder (EmitContext *ctx)
1385 LLVMBuilderRef builder = LLVMCreateBuilder ();
1387 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1393 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1395 char *callee_name = mono_aot_get_plt_symbol (type, data);
1396 LLVMValueRef callee;
1397 MonoJumpInfo *ji = NULL;
1402 if (ctx->cfg->compile_aot)
1403 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1404 mono_add_patch_info (ctx->cfg, 0, type, data);
1407 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1409 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1411 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1413 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1416 if (ctx->cfg->compile_aot) {
1417 ji = g_new0 (MonoJumpInfo, 1);
1419 ji->data.target = data;
1421 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1428 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1430 MonoMethodHeader *header = cfg->header;
1431 MonoExceptionClause *clause;
1435 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1436 return (bb->region >> 8) - 1;
1439 for (i = 0; i < header->num_clauses; ++i) {
1440 clause = &header->clauses [i];
1442 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1450 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1452 LLVMValueRef md_arg;
1455 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1456 md_arg = LLVMMDString ("mono", 4);
1457 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1461 set_invariant_load_flag (LLVMValueRef v)
1463 LLVMValueRef md_arg;
1465 const char *flag_name;
1467 // FIXME: Cache this
1468 flag_name = "invariant.load";
1469 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1470 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1471 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1477 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1481 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1483 MonoCompile *cfg = ctx->cfg;
1485 LLVMBuilderRef builder = *builder_ref;
1488 clause_index = get_handler_clause (cfg, bb);
1490 if (clause_index != -1) {
1491 MonoMethodHeader *header = cfg->header;
1492 MonoExceptionClause *ec = &header->clauses [clause_index];
1493 MonoBasicBlock *tblock;
1494 LLVMBasicBlockRef ex_bb, noex_bb;
1497 * Have to use an invoke instead of a call, branching to the
1498 * handler bblock of the clause containing this bblock.
1501 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1503 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1506 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1508 ex_bb = get_bb (ctx, tblock);
1510 noex_bb = gen_bb (ctx, "NOEX_BB");
1513 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1515 builder = ctx->builder = create_builder (ctx);
1516 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1518 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1520 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1521 ctx->builder = builder;
1524 *builder_ref = ctx->builder;
1530 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1532 const char *intrins_name;
1533 LLVMValueRef args [16], res;
1534 LLVMTypeRef addr_type;
1536 if (is_faulting && bb->region != -1) {
1537 LLVMAtomicOrdering ordering;
1540 case LLVM_BARRIER_NONE:
1541 ordering = LLVMAtomicOrderingNotAtomic;
1543 case LLVM_BARRIER_ACQ:
1544 ordering = LLVMAtomicOrderingAcquire;
1546 case LLVM_BARRIER_SEQ:
1547 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1550 g_assert_not_reached ();
1555 * We handle loads which can fault by calling a mono specific intrinsic
1556 * using an invoke, so they are handled properly inside try blocks.
1557 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1558 * are marked with IntrReadArgMem.
1562 intrins_name = "llvm.mono.load.i8.p0i8";
1565 intrins_name = "llvm.mono.load.i16.p0i16";
1568 intrins_name = "llvm.mono.load.i32.p0i32";
1571 intrins_name = "llvm.mono.load.i64.p0i64";
1574 g_assert_not_reached ();
1577 addr_type = LLVMTypeOf (addr);
1578 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1579 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1582 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1583 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1584 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1585 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1587 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1588 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1589 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1590 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1597 * We emit volatile loads for loads which can fault, because otherwise
1598 * LLVM will generate invalid code when encountering a load from a
1601 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1603 /* Mark it with a custom metadata */
1606 set_metadata_flag (res, "mono.faulting.load");
1614 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1616 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1620 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1622 const char *intrins_name;
1623 LLVMValueRef args [16];
1625 if (is_faulting && bb->region != -1) {
1626 LLVMAtomicOrdering ordering;
1629 case LLVM_BARRIER_NONE:
1630 ordering = LLVMAtomicOrderingNotAtomic;
1632 case LLVM_BARRIER_REL:
1633 ordering = LLVMAtomicOrderingRelease;
1635 case LLVM_BARRIER_SEQ:
1636 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1639 g_assert_not_reached ();
1645 intrins_name = "llvm.mono.store.i8.p0i8";
1648 intrins_name = "llvm.mono.store.i16.p0i16";
1651 intrins_name = "llvm.mono.store.i32.p0i32";
1654 intrins_name = "llvm.mono.store.i64.p0i64";
1657 g_assert_not_reached ();
1660 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1661 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1662 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1667 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1668 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1669 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1670 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1672 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1677 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1679 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1683 * emit_cond_system_exception:
1685 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1686 * Might set the ctx exception.
1689 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1691 LLVMBasicBlockRef ex_bb, noex_bb;
1692 LLVMBuilderRef builder;
1693 MonoClass *exc_class;
1694 LLVMValueRef args [2];
1696 ex_bb = gen_bb (ctx, "EX_BB");
1697 noex_bb = gen_bb (ctx, "NOEX_BB");
1699 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1701 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1702 g_assert (exc_class);
1704 /* Emit exception throwing code */
1705 builder = create_builder (ctx);
1706 LLVMPositionBuilderAtEnd (builder, ex_bb);
1708 if (!ctx->lmodule->throw_corlib_exception) {
1709 LLVMValueRef callee;
1711 const char *icall_name;
1713 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1714 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1715 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1716 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1717 /* This will become i8* */
1718 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1719 sig = sig_to_llvm_sig (ctx, throw_sig);
1721 if (ctx->cfg->compile_aot) {
1722 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1724 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1727 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1728 * - On x86, LLVM generated code doesn't push the arguments
1729 * - The trampoline takes the throw address as an arguments, not a pc offset.
1731 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1734 mono_memory_barrier ();
1735 ctx->lmodule->throw_corlib_exception = callee;
1738 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1739 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1741 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1744 * The LLVM mono branch contains changes so a block address can be passed as an
1745 * argument to a call.
1747 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1748 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1750 LLVMBuildUnreachable (builder);
1752 ctx->builder = create_builder (ctx);
1753 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1755 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1762 * emit_args_to_vtype:
1764 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1767 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1769 int j, size, nslots;
1771 size = get_vtype_size (t);
1773 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1774 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1777 if (ainfo->storage == LLVMArgAsFpArgs)
1778 nslots = ainfo->nslots;
1782 for (j = 0; j < nslots; ++j) {
1783 LLVMValueRef index [2], addr, daddr;
1784 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1785 LLVMTypeRef part_type;
1787 if (ainfo->pair_storage [j] == LLVMArgNone)
1790 switch (ainfo->pair_storage [j]) {
1791 case LLVMArgInIReg: {
1792 part_type = LLVMIntType (part_size * 8);
1793 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1794 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1795 addr = LLVMBuildGEP (builder, address, index, 1, "");
1797 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1798 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1799 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1801 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1804 case LLVMArgInFPReg: {
1805 LLVMTypeRef arg_type;
1807 if (ainfo->esize == 8)
1808 arg_type = LLVMDoubleType ();
1810 arg_type = LLVMFloatType ();
1812 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1813 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1814 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1815 LLVMBuildStore (builder, args [j], addr);
1821 g_assert_not_reached ();
1824 size -= sizeof (gpointer);
1829 * emit_vtype_to_args:
1831 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1832 * into ARGS, and the number of arguments into NARGS.
1835 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1838 int j, size, nslots;
1839 LLVMTypeRef arg_type;
1841 size = get_vtype_size (t);
1843 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1844 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1846 if (ainfo->storage == LLVMArgAsFpArgs)
1847 nslots = ainfo->nslots;
1850 for (j = 0; j < nslots; ++j) {
1851 LLVMValueRef index [2], addr, daddr;
1852 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1854 if (ainfo->pair_storage [j] == LLVMArgNone)
1857 switch (ainfo->pair_storage [j]) {
1859 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1860 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1861 addr = LLVMBuildGEP (builder, address, index, 1, "");
1863 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1864 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1865 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1867 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1869 case LLVMArgInFPReg:
1870 if (ainfo->esize == 8)
1871 arg_type = LLVMDoubleType ();
1873 arg_type = LLVMFloatType ();
1874 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1875 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1876 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1877 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1882 g_assert_not_reached ();
1884 size -= sizeof (gpointer);
1891 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1894 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1895 * get executed every time control reaches them.
1897 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1899 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1900 return ctx->last_alloca;
1904 build_alloca (EmitContext *ctx, MonoType *t)
1906 MonoClass *k = mono_class_from_mono_type (t);
1909 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1912 align = mono_class_min_align (k);
1914 /* Sometimes align is not a power of 2 */
1915 while (mono_is_power_of_two (align) == -1)
1918 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1922 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1925 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1928 lmodule->used = g_ptr_array_sized_new (16);
1929 g_ptr_array_add (lmodule->used, global);
1933 emit_llvm_used (MonoLLVMModule *lmodule)
1935 LLVMModuleRef module = lmodule->module;
1936 LLVMTypeRef used_type;
1937 LLVMValueRef used, *used_elem;
1943 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1944 used = LLVMAddGlobal (module, used_type, "llvm.used");
1945 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1946 for (i = 0; i < lmodule->used->len; ++i)
1947 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1948 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1949 LLVMSetLinkage (used, LLVMAppendingLinkage);
1950 LLVMSetSection (used, "llvm.metadata");
1954 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1956 gboolean need_div_check = FALSE;
1958 #ifdef MONO_ARCH_NEED_DIV_CHECK
1959 need_div_check = TRUE;
1962 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1963 need_div_check = TRUE;
1965 if (!need_div_check)
1968 switch (ins->opcode) {
1981 case OP_IDIV_UN_IMM:
1982 case OP_LDIV_UN_IMM:
1983 case OP_IREM_UN_IMM:
1984 case OP_LREM_UN_IMM: {
1986 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1987 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
1989 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
1990 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
1991 CHECK_FAILURE (ctx);
1992 builder = ctx->builder;
1994 /* b == -1 && a == 0x80000000 */
1996 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
1997 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
1998 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2000 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2001 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2002 CHECK_FAILURE (ctx);
2003 builder = ctx->builder;
2018 * Emit code to load/convert arguments.
2021 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2024 MonoCompile *cfg = ctx->cfg;
2025 MonoMethodSignature *sig = ctx->sig;
2026 LLVMCallInfo *linfo = ctx->linfo;
2029 ctx->alloca_builder = create_builder (ctx);
2032 * Handle indirect/volatile variables by allocating memory for them
2033 * using 'alloca', and storing their address in a temporary.
2035 for (i = 0; i < cfg->num_varinfo; ++i) {
2036 MonoInst *var = cfg->varinfo [i];
2039 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2040 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2041 CHECK_FAILURE (ctx);
2042 /* Could be already created by an OP_VPHI */
2043 if (!ctx->addresses [var->dreg])
2044 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2045 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2049 for (i = 0; i < sig->param_count; ++i) {
2050 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2051 int reg = cfg->args [i + sig->hasthis]->dreg;
2053 switch (ainfo->storage) {
2054 case LLVMArgVtypeInReg:
2055 case LLVMArgAsFpArgs: {
2056 LLVMValueRef args [8];
2059 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2060 memset (args, 0, sizeof (args));
2061 pindex = ctx->pindexes [i];
2062 if (ainfo->storage == LLVMArgVtypeInReg) {
2063 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2064 if (ainfo->pair_storage [1] != LLVMArgNone)
2065 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2067 g_assert (ainfo->nslots <= 8);
2068 for (j = 0; j < ainfo->nslots; ++j)
2069 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2071 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2073 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2075 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2076 /* Treat these as normal values */
2077 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2081 case LLVMArgVtypeByVal: {
2082 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2084 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2085 /* Treat these as normal values */
2086 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2090 case LLVMArgAsIArgs: {
2091 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2093 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2095 /* The argument is received as an array of ints, store it into the real argument */
2096 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2100 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]));
2106 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2108 emit_volatile_store (ctx, cfg->args [0]->dreg);
2109 for (i = 0; i < sig->param_count; ++i)
2110 if (!mini_type_is_vtype (cfg, sig->params [i]))
2111 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2113 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2114 LLVMValueRef this_alloc;
2117 * The exception handling code needs the location where the this argument was
2118 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2119 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2120 * location into the LSDA.
2122 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2123 /* This volatile store will keep the alloca alive */
2124 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2126 set_metadata_flag (this_alloc, "mono.this");
2129 if (cfg->rgctx_var) {
2130 LLVMValueRef rgctx_alloc, store;
2133 * We handle the rgctx arg similarly to the this pointer.
2135 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2136 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2137 /* This volatile store will keep the alloca alive */
2138 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2140 set_metadata_flag (rgctx_alloc, "mono.this");
2143 /* Compute nesting between clauses */
2144 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2145 for (i = 0; i < cfg->header->num_clauses; ++i) {
2146 for (j = 0; j < cfg->header->num_clauses; ++j) {
2147 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2148 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2150 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2151 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2156 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2157 * it needs to continue normally, or return back to the exception handling system.
2159 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2163 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2166 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2167 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2168 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2170 if (bb->in_scount == 0) {
2173 sprintf (name, "finally_ind_bb%d", bb->block_num);
2174 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2175 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2177 ctx->bblocks [bb->block_num].finally_ind = val;
2179 /* Create a variable to hold the exception var */
2181 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2185 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2186 * LLVM bblock containing a landing pad causes problems for the
2187 * LLVM optimizer passes.
2189 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2190 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2197 /* Have to export this for AOT */
2199 mono_personality (void)
2202 g_assert_not_reached ();
2206 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2208 MonoCompile *cfg = ctx->cfg;
2209 LLVMModuleRef module = ctx->module;
2210 LLVMValueRef *values = ctx->values;
2211 LLVMValueRef *addresses = ctx->addresses;
2212 MonoCallInst *call = (MonoCallInst*)ins;
2213 MonoMethodSignature *sig = call->signature;
2214 LLVMValueRef callee = NULL, lcall;
2216 LLVMCallInfo *cinfo;
2220 LLVMTypeRef llvm_sig;
2222 gboolean virtual, calli;
2223 LLVMBuilderRef builder = *builder_ref;
2226 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2227 LLVM_FAILURE (ctx, "non-default callconv");
2229 cinfo = call->cinfo;
2230 if (call->rgctx_arg_reg)
2231 cinfo->rgctx_arg = TRUE;
2232 if (call->imt_arg_reg)
2233 cinfo->imt_arg = TRUE;
2235 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2237 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2238 CHECK_FAILURE (ctx);
2240 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);
2241 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);
2243 /* FIXME: Avoid creating duplicate methods */
2245 if (ins->flags & MONO_INST_HAS_METHOD) {
2249 if (cfg->compile_aot) {
2250 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2252 LLVM_FAILURE (ctx, "can't encode patch");
2254 callee = LLVMAddFunction (module, "", llvm_sig);
2257 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2259 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2263 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2264 /* LLVM miscompiles async methods */
2265 LLVM_FAILURE (ctx, "#13734");
2268 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2274 memset (&ji, 0, sizeof (ji));
2275 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2276 ji.data.target = info->name;
2278 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2280 if (cfg->compile_aot) {
2281 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2283 LLVM_FAILURE (ctx, "can't encode patch");
2285 callee = LLVMAddFunction (module, "", llvm_sig);
2286 target = (gpointer)mono_icall_get_wrapper (info);
2287 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2290 if (cfg->compile_aot) {
2292 if (cfg->abs_patches) {
2293 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2295 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2297 LLVM_FAILURE (ctx, "can't encode patch");
2301 LLVM_FAILURE (ctx, "aot");
2303 callee = LLVMAddFunction (module, "", llvm_sig);
2305 if (cfg->abs_patches) {
2306 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2309 * FIXME: Some trampolines might have
2310 * their own calling convention on some platforms.
2312 #ifndef TARGET_AMD64
2313 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2314 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
2315 LLVM_FAILURE (ctx, "trampoline with own cconv");
2317 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2318 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2322 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2328 int size = sizeof (gpointer);
2331 g_assert (ins->inst_offset % size == 0);
2332 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2334 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2336 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2338 if (ins->flags & MONO_INST_HAS_METHOD) {
2343 * Collect and convert arguments
2345 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2346 len = sizeof (LLVMValueRef) * nargs;
2347 args = alloca (len);
2348 memset (args, 0, len);
2349 l = call->out_ireg_args;
2351 if (call->rgctx_arg_reg) {
2352 g_assert (values [call->rgctx_arg_reg]);
2353 g_assert (sinfo.rgctx_arg_pindex < nargs);
2355 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2356 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2357 * it using a volatile load.
2360 if (!ctx->imt_rgctx_loc)
2361 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2362 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2363 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2365 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2368 if (call->imt_arg_reg) {
2369 g_assert (values [call->imt_arg_reg]);
2370 g_assert (sinfo.imt_arg_pindex < nargs);
2372 if (!ctx->imt_rgctx_loc)
2373 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2374 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2375 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2377 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2382 if (!addresses [call->inst.dreg])
2383 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2384 g_assert (sinfo.vret_arg_pindex < nargs);
2385 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2388 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2391 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2395 pindex = sinfo.this_arg_pindex;
2397 pindex = sinfo.pindexes [i - 1];
2399 pindex = sinfo.pindexes [i];
2402 regpair = (guint32)(gssize)(l->data);
2403 reg = regpair & 0xffffff;
2404 args [pindex] = values [reg];
2405 switch (ainfo->storage) {
2406 case LLVMArgVtypeInReg:
2407 case LLVMArgAsFpArgs: {
2410 g_assert (addresses [reg]);
2411 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2415 // FIXME: Get rid of the VMOVE
2418 case LLVMArgVtypeByVal:
2419 g_assert (addresses [reg]);
2420 args [pindex] = addresses [reg];
2422 case LLVMArgAsIArgs:
2423 g_assert (addresses [reg]);
2424 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2427 g_assert (args [pindex]);
2428 if (i == 0 && sig->hasthis)
2429 args [pindex] = convert (ctx, args [pindex], ThisType ());
2431 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2434 g_assert (pindex <= nargs);
2439 // FIXME: Align call sites
2445 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2448 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2450 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2451 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2453 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2454 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2456 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2458 if (call->rgctx_arg_reg)
2459 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2460 if (call->imt_arg_reg)
2461 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2463 /* Add byval attributes if needed */
2464 for (i = 0; i < sig->param_count; ++i) {
2465 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2467 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2468 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2473 * Convert the result
2476 switch (cinfo->ret.storage) {
2477 case LLVMArgVtypeInReg: {
2478 LLVMValueRef regs [2];
2480 if (!addresses [ins->dreg])
2481 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2483 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2484 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2485 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2486 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2489 case LLVMArgVtypeByVal:
2490 if (!addresses [call->inst.dreg])
2491 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2492 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2494 case LLVMArgFpStruct:
2495 if (!addresses [call->inst.dreg])
2496 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2497 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2500 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2501 /* If the method returns an unsigned value, need to zext it */
2502 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));
2506 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2507 /* If the method returns an unsigned value, need to zext it */
2508 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));
2512 if (!addresses [call->inst.dreg])
2513 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2514 g_assert (sinfo.vret_arg_pindex < nargs);
2515 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2518 *builder_ref = ctx->builder;
2520 g_free (sinfo.pindexes);
2528 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2530 MonoCompile *cfg = ctx->cfg;
2531 LLVMValueRef *values = ctx->values;
2532 LLVMModuleRef module = ctx->module;
2533 BBInfo *bblocks = ctx->bblocks;
2535 LLVMValueRef personality;
2536 LLVMValueRef landing_pad;
2537 LLVMBasicBlockRef target_bb;
2539 static gint32 mapping_inited;
2540 static int ti_generator;
2543 LLVMValueRef type_info;
2547 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2549 if (cfg->compile_aot) {
2550 /* Use a dummy personality function */
2551 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2552 g_assert (personality);
2554 personality = LLVMGetNamedFunction (module, "mono_personality");
2555 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2556 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2559 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2561 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2564 * Create the type info
2566 sprintf (ti_name, "type_info_%d", ti_generator);
2569 if (cfg->compile_aot) {
2570 /* decode_eh_frame () in aot-runtime.c will decode this */
2571 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2572 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2575 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2577 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2580 * After the cfg mempool is freed, the type info will point to stale memory,
2581 * but this is not a problem, since we decode it once in exception_cb during
2584 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2585 *(gint32*)ti = clause_index;
2587 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2589 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2593 LLVMTypeRef members [2], ret_type;
2595 members [0] = i8ptr;
2596 members [1] = LLVMInt32Type ();
2597 ret_type = LLVMStructType (members, 2, FALSE);
2599 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2600 LLVMAddClause (landing_pad, type_info);
2602 /* Store the exception into the exvar */
2604 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2608 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2609 * code expects control to be transferred to this landing pad even in the
2610 * presence of nested clauses. The landing pad needs to branch to the landing
2611 * pads belonging to nested clauses based on the selector value returned by
2612 * the landing pad instruction, which is passed to the landing pad in a
2613 * register by the EH code.
2615 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2616 g_assert (target_bb);
2619 * Branch to the correct landing pad
2621 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2622 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2624 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2625 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2626 MonoBasicBlock *handler_bb;
2628 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2629 g_assert (handler_bb);
2631 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2632 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2635 /* Start a new bblock which CALL_HANDLER can branch to */
2636 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2638 ctx->builder = builder = create_builder (ctx);
2639 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2641 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2643 /* Store the exception into the IL level exvar */
2644 if (bb->in_scount == 1) {
2645 g_assert (bb->in_scount == 1);
2646 exvar = bb->in_stack [0];
2648 // FIXME: This is shared with filter clauses ?
2649 g_assert (!values [exvar->dreg]);
2651 g_assert (ctx->ex_var);
2652 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2653 emit_volatile_store (ctx, exvar->dreg);
2659 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2661 MonoCompile *cfg = ctx->cfg;
2662 MonoMethodSignature *sig = ctx->sig;
2663 LLVMValueRef method = ctx->lmethod;
2664 LLVMValueRef *values = ctx->values;
2665 LLVMValueRef *addresses = ctx->addresses;
2666 LLVMCallInfo *linfo = ctx->linfo;
2667 LLVMModuleRef module = ctx->module;
2668 BBInfo *bblocks = ctx->bblocks;
2670 LLVMBasicBlockRef cbb;
2671 LLVMBuilderRef builder, starting_builder;
2672 gboolean has_terminator;
2674 LLVMValueRef lhs, rhs;
2677 cbb = get_bb (ctx, bb);
2678 builder = create_builder (ctx);
2679 ctx->builder = builder;
2680 LLVMPositionBuilderAtEnd (builder, cbb);
2682 if (bb == cfg->bb_entry)
2683 emit_entry_bb (ctx, builder);
2684 CHECK_FAILURE (ctx);
2686 if (bb->flags & BB_EXCEPTION_HANDLER) {
2687 if (!bblocks [bb->block_num].invoke_target) {
2689 * LLVM asserts if llvm.eh.selector is called from a bblock which
2690 * doesn't have an invoke pointing at it.
2691 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2693 LLVM_FAILURE (ctx, "handler without invokes");
2696 emit_handler_start (ctx, bb, builder);
2697 CHECK_FAILURE (ctx);
2698 builder = ctx->builder;
2701 has_terminator = FALSE;
2702 starting_builder = builder;
2703 for (ins = bb->code; ins; ins = ins->next) {
2704 const char *spec = LLVM_INS_INFO (ins->opcode);
2706 char dname_buf [128];
2708 emit_dbg_loc (ctx, builder, ins->cil_code);
2711 if (nins > 5000 && builder == starting_builder) {
2712 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2713 LLVM_FAILURE (ctx, "basic block too long");
2717 /* There could be instructions after a terminator, skip them */
2720 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2721 sprintf (dname_buf, "t%d", ins->dreg);
2725 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2726 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2728 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2729 lhs = emit_volatile_load (ctx, ins->sreg1);
2731 /* It is ok for SETRET to have an uninitialized argument */
2732 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2733 LLVM_FAILURE (ctx, "sreg1");
2734 lhs = values [ins->sreg1];
2740 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2741 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2742 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2743 rhs = emit_volatile_load (ctx, ins->sreg2);
2745 if (!values [ins->sreg2])
2746 LLVM_FAILURE (ctx, "sreg2");
2747 rhs = values [ins->sreg2];
2753 //mono_print_ins (ins);
2754 switch (ins->opcode) {
2757 case OP_LIVERANGE_START:
2758 case OP_LIVERANGE_END:
2761 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2764 #if SIZEOF_VOID_P == 4
2765 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2767 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2771 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2775 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2777 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2779 case OP_DUMMY_ICONST:
2780 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2782 case OP_DUMMY_I8CONST:
2783 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2785 case OP_DUMMY_R8CONST:
2786 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2789 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2790 has_terminator = TRUE;
2796 LLVMBasicBlockRef new_bb;
2797 LLVMBuilderRef new_builder;
2799 // The default branch is already handled
2800 // FIXME: Handle it here
2802 /* Start new bblock */
2803 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2804 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2806 lhs = convert (ctx, lhs, LLVMInt32Type ());
2807 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2808 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2809 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2811 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2814 new_builder = create_builder (ctx);
2815 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2816 LLVMBuildUnreachable (new_builder);
2818 has_terminator = TRUE;
2819 g_assert (!ins->next);
2825 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2826 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2827 LLVMValueRef part1, retval;
2830 size = get_vtype_size (sig->ret);
2832 g_assert (addresses [ins->sreg1]);
2834 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2835 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2837 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2839 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2841 LLVMBuildRet (builder, retval);
2845 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2846 LLVMValueRef retval;
2848 g_assert (addresses [ins->sreg1]);
2849 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2850 LLVMBuildRet (builder, retval);
2854 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2855 LLVMBuildRetVoid (builder);
2859 if (linfo->ret.storage == LLVMArgFpStruct) {
2860 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2861 LLVMValueRef retval;
2863 g_assert (addresses [ins->sreg1]);
2864 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2865 LLVMBuildRet (builder, retval);
2869 if (!lhs || ctx->is_dead [ins->sreg1]) {
2871 * The method did not set its return value, probably because it
2872 * ends with a throw.
2875 LLVMBuildRetVoid (builder);
2877 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2879 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2881 has_terminator = TRUE;
2888 case OP_ICOMPARE_IMM:
2889 case OP_LCOMPARE_IMM:
2890 case OP_COMPARE_IMM: {
2894 if (ins->next->opcode == OP_NOP)
2897 if (ins->next->opcode == OP_BR)
2898 /* The comparison result is not needed */
2901 rel = mono_opcode_to_cond (ins->next->opcode);
2903 if (ins->opcode == OP_ICOMPARE_IMM) {
2904 lhs = convert (ctx, lhs, LLVMInt32Type ());
2905 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2907 if (ins->opcode == OP_LCOMPARE_IMM) {
2908 lhs = convert (ctx, lhs, LLVMInt64Type ());
2909 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2911 if (ins->opcode == OP_LCOMPARE) {
2912 lhs = convert (ctx, lhs, LLVMInt64Type ());
2913 rhs = convert (ctx, rhs, LLVMInt64Type ());
2915 if (ins->opcode == OP_ICOMPARE) {
2916 lhs = convert (ctx, lhs, LLVMInt32Type ());
2917 rhs = convert (ctx, rhs, LLVMInt32Type ());
2921 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2922 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2923 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2924 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2927 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2928 if (ins->opcode == OP_FCOMPARE) {
2929 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2930 } else if (ins->opcode == OP_RCOMPARE) {
2931 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2932 } else if (ins->opcode == OP_COMPARE_IMM) {
2933 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2934 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2936 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2937 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2938 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2939 /* The immediate is encoded in two fields */
2940 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2941 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2943 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2946 else if (ins->opcode == OP_COMPARE) {
2947 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2948 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2950 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2952 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2954 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2955 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2957 * If the target bb contains PHI instructions, LLVM requires
2958 * two PHI entries for this bblock, while we only generate one.
2959 * So convert this to an unconditional bblock. (bxc #171).
2961 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2963 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2965 has_terminator = TRUE;
2966 } else if (MONO_IS_SETCC (ins->next)) {
2967 sprintf (dname_buf, "t%d", ins->next->dreg);
2969 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2971 /* Add stores for volatile variables */
2972 emit_volatile_store (ctx, ins->next->dreg);
2973 } else if (MONO_IS_COND_EXC (ins->next)) {
2974 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2975 CHECK_FAILURE (ctx);
2976 builder = ctx->builder;
2978 LLVM_FAILURE (ctx, "next");
2992 rel = mono_opcode_to_cond (ins->opcode);
2994 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2995 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3006 rel = mono_opcode_to_cond (ins->opcode);
3008 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3009 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3017 gboolean empty = TRUE;
3019 /* Check that all input bblocks really branch to us */
3020 for (i = 0; i < bb->in_count; ++i) {
3021 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3022 ins->inst_phi_args [i + 1] = -1;
3028 /* LLVM doesn't like phi instructions with zero operands */
3029 ctx->is_dead [ins->dreg] = TRUE;
3033 /* Created earlier, insert it now */
3034 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3036 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3037 int sreg1 = ins->inst_phi_args [i + 1];
3041 * Count the number of times the incoming bblock branches to us,
3042 * since llvm requires a separate entry for each.
3044 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3045 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3048 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3049 if (switch_ins->inst_many_bb [j] == bb)
3056 /* Remember for later */
3057 for (j = 0; j < count; ++j) {
3058 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3061 node->in_bb = bb->in_bb [i];
3063 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);
3073 values [ins->dreg] = lhs;
3077 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3080 values [ins->dreg] = lhs;
3082 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3084 * This is added by the spilling pass in case of the JIT,
3085 * but we have to do it ourselves.
3087 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3091 case OP_MOVE_F_TO_I4: {
3092 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3095 case OP_MOVE_I4_TO_F: {
3096 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3099 case OP_MOVE_F_TO_I8: {
3100 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3103 case OP_MOVE_I8_TO_F: {
3104 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3137 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3138 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3140 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3141 CHECK_FAILURE (ctx);
3142 builder = ctx->builder;
3144 switch (ins->opcode) {
3147 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3151 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3155 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3159 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3163 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3167 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3171 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3175 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3179 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3183 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3187 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3191 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3195 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3199 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3203 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3206 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3209 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3213 g_assert_not_reached ();
3220 lhs = convert (ctx, lhs, LLVMFloatType ());
3221 rhs = convert (ctx, rhs, LLVMFloatType ());
3222 switch (ins->opcode) {
3224 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3227 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3230 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3233 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3236 g_assert_not_reached ();
3245 case OP_IREM_UN_IMM:
3247 case OP_IDIV_UN_IMM:
3253 case OP_ISHR_UN_IMM:
3262 case OP_LSHR_UN_IMM:
3268 case OP_SHR_UN_IMM: {
3271 if (spec [MONO_INST_SRC1] == 'l') {
3272 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3274 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3277 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3278 CHECK_FAILURE (ctx);
3279 builder = ctx->builder;
3281 #if SIZEOF_VOID_P == 4
3282 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3283 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3286 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3287 lhs = convert (ctx, lhs, IntPtrType ());
3288 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3289 switch (ins->opcode) {
3293 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3297 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3301 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3305 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3307 case OP_IDIV_UN_IMM:
3308 case OP_LDIV_UN_IMM:
3309 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3313 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3315 case OP_IREM_UN_IMM:
3316 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3321 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3325 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3329 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3334 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3339 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3341 case OP_ISHR_UN_IMM:
3342 /* This is used to implement conv.u4, so the lhs could be an i8 */
3343 lhs = convert (ctx, lhs, LLVMInt32Type ());
3344 imm = convert (ctx, imm, LLVMInt32Type ());
3345 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3347 case OP_LSHR_UN_IMM:
3349 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3352 g_assert_not_reached ();
3357 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3360 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3363 lhs = convert (ctx, lhs, LLVMDoubleType ());
3364 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3367 lhs = convert (ctx, lhs, LLVMFloatType ());
3368 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3371 guint32 v = 0xffffffff;
3372 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3376 guint64 v = 0xffffffffffffffffLL;
3377 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3380 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3382 LLVMValueRef v1, v2;
3384 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3385 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3386 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3391 case OP_ICONV_TO_I1:
3392 case OP_ICONV_TO_I2:
3393 case OP_ICONV_TO_I4:
3394 case OP_ICONV_TO_U1:
3395 case OP_ICONV_TO_U2:
3396 case OP_ICONV_TO_U4:
3397 case OP_LCONV_TO_I1:
3398 case OP_LCONV_TO_I2:
3399 case OP_LCONV_TO_U1:
3400 case OP_LCONV_TO_U2:
3401 case OP_LCONV_TO_U4: {
3404 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);
3406 /* Have to do two casts since our vregs have type int */
3407 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3409 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3411 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3414 case OP_ICONV_TO_I8:
3415 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3417 case OP_ICONV_TO_U8:
3418 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3420 case OP_FCONV_TO_I4:
3421 case OP_RCONV_TO_I4:
3422 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3424 case OP_FCONV_TO_I1:
3425 case OP_RCONV_TO_I1:
3426 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3428 case OP_FCONV_TO_U1:
3429 case OP_RCONV_TO_U1:
3430 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3432 case OP_FCONV_TO_I2:
3433 case OP_RCONV_TO_I2:
3434 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3436 case OP_FCONV_TO_U2:
3437 case OP_RCONV_TO_U2:
3438 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3440 case OP_FCONV_TO_I8:
3441 case OP_RCONV_TO_I8:
3442 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3445 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3447 case OP_ICONV_TO_R8:
3448 case OP_LCONV_TO_R8:
3449 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3451 case OP_LCONV_TO_R_UN:
3452 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3454 #if SIZEOF_VOID_P == 4
3457 case OP_LCONV_TO_I4:
3458 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3460 case OP_ICONV_TO_R4:
3461 case OP_LCONV_TO_R4:
3462 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3464 values [ins->dreg] = v;
3466 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3468 case OP_FCONV_TO_R4:
3469 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3471 values [ins->dreg] = v;
3473 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3475 case OP_RCONV_TO_R8:
3476 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3478 case OP_RCONV_TO_R4:
3479 values [ins->dreg] = lhs;
3482 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3485 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3488 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3490 case OP_LOCALLOC_IMM: {
3493 guint32 size = ins->inst_imm;
3494 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3496 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3498 if (ins->flags & MONO_INST_INIT) {
3499 LLVMValueRef args [5];
3502 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3503 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3504 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3505 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3506 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3509 values [ins->dreg] = v;
3513 LLVMValueRef v, size;
3515 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), "");
3517 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3519 if (ins->flags & MONO_INST_INIT) {
3520 LLVMValueRef args [5];
3523 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3525 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3526 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3527 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3529 values [ins->dreg] = v;
3533 case OP_LOADI1_MEMBASE:
3534 case OP_LOADU1_MEMBASE:
3535 case OP_LOADI2_MEMBASE:
3536 case OP_LOADU2_MEMBASE:
3537 case OP_LOADI4_MEMBASE:
3538 case OP_LOADU4_MEMBASE:
3539 case OP_LOADI8_MEMBASE:
3540 case OP_LOADR4_MEMBASE:
3541 case OP_LOADR8_MEMBASE:
3542 case OP_LOAD_MEMBASE:
3550 LLVMValueRef base, index, addr;
3552 gboolean sext = FALSE, zext = FALSE;
3553 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3555 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3560 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)) {
3561 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3566 if (ins->inst_offset == 0) {
3568 } else if (ins->inst_offset % size != 0) {
3569 /* Unaligned load */
3570 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3571 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3573 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3574 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3578 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3580 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3582 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3584 * These will signal LLVM that these loads do not alias any stores, and
3585 * they can't fail, allowing them to be hoisted out of loops.
3587 set_invariant_load_flag (values [ins->dreg]);
3588 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3592 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3594 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3595 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3596 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3600 case OP_STOREI1_MEMBASE_REG:
3601 case OP_STOREI2_MEMBASE_REG:
3602 case OP_STOREI4_MEMBASE_REG:
3603 case OP_STOREI8_MEMBASE_REG:
3604 case OP_STORER4_MEMBASE_REG:
3605 case OP_STORER8_MEMBASE_REG:
3606 case OP_STORE_MEMBASE_REG: {
3608 LLVMValueRef index, addr;
3610 gboolean sext = FALSE, zext = FALSE;
3611 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3613 if (!values [ins->inst_destbasereg])
3614 LLVM_FAILURE (ctx, "inst_destbasereg");
3616 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3618 if (ins->inst_offset % size != 0) {
3619 /* Unaligned store */
3620 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3621 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3623 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3624 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3626 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3630 case OP_STOREI1_MEMBASE_IMM:
3631 case OP_STOREI2_MEMBASE_IMM:
3632 case OP_STOREI4_MEMBASE_IMM:
3633 case OP_STOREI8_MEMBASE_IMM:
3634 case OP_STORE_MEMBASE_IMM: {
3636 LLVMValueRef index, addr;
3638 gboolean sext = FALSE, zext = FALSE;
3639 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3641 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3643 if (ins->inst_offset % size != 0) {
3644 /* Unaligned store */
3645 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3646 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3648 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3649 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3651 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3656 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3658 case OP_OUTARG_VTRETADDR:
3666 case OP_VOIDCALL_MEMBASE:
3667 case OP_CALL_MEMBASE:
3668 case OP_LCALL_MEMBASE:
3669 case OP_FCALL_MEMBASE:
3670 case OP_RCALL_MEMBASE:
3671 case OP_VCALL_MEMBASE:
3672 case OP_VOIDCALL_REG:
3677 case OP_VCALL_REG: {
3678 process_call (ctx, bb, &builder, ins);
3679 CHECK_FAILURE (ctx);
3684 LLVMValueRef indexes [2];
3686 LLVMValueRef got_entry_addr;
3689 * FIXME: Can't allocate from the cfg mempool since that is freed if
3690 * the LLVM compile fails.
3692 ji = g_new0 (MonoJumpInfo, 1);
3693 ji->type = (MonoJumpInfoType)ins->inst_i1;
3694 ji->data.target = ins->inst_p0;
3696 ji = mono_aot_patch_info_dup (ji);
3698 ji->next = cfg->patch_info;
3699 cfg->patch_info = ji;
3701 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3702 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3703 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3705 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3706 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3707 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3709 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3710 set_invariant_load_flag (values [ins->dreg]);
3713 case OP_NOT_REACHED:
3714 LLVMBuildUnreachable (builder);
3715 has_terminator = TRUE;
3716 g_assert (bb->block_num < cfg->max_block_num);
3717 ctx->unreachable [bb->block_num] = TRUE;
3718 /* Might have instructions after this */
3720 MonoInst *next = ins->next;
3722 * FIXME: If later code uses the regs defined by these instructions,
3723 * compilation will fail.
3725 MONO_DELETE_INS (bb, next);
3729 MonoInst *var = ins->inst_p0;
3731 values [ins->dreg] = addresses [var->dreg];
3735 LLVMValueRef args [1];
3737 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3738 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3742 LLVMValueRef args [1];
3744 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3745 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3749 LLVMValueRef args [1];
3752 /* This no longer seems to happen */
3754 * LLVM optimizes sqrt(nan) into undefined in
3755 * lib/Analysis/ConstantFolding.cpp
3756 * Also, sqrt(NegativeInfinity) is optimized into 0.
3758 LLVM_FAILURE (ctx, "sqrt");
3760 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3761 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3765 LLVMValueRef args [1];
3767 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3768 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3782 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3783 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3785 switch (ins->opcode) {
3788 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3792 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3796 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3800 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3803 g_assert_not_reached ();
3806 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3809 case OP_ATOMIC_EXCHANGE_I4:
3810 case OP_ATOMIC_EXCHANGE_I8: {
3811 LLVMValueRef args [2];
3814 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3815 t = LLVMInt32Type ();
3817 t = LLVMInt64Type ();
3819 g_assert (ins->inst_offset == 0);
3821 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3822 args [1] = convert (ctx, rhs, t);
3824 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3827 case OP_ATOMIC_ADD_I4:
3828 case OP_ATOMIC_ADD_I8: {
3829 LLVMValueRef args [2];
3832 if (ins->opcode == OP_ATOMIC_ADD_I4)
3833 t = LLVMInt32Type ();
3835 t = LLVMInt64Type ();
3837 g_assert (ins->inst_offset == 0);
3839 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3840 args [1] = convert (ctx, rhs, t);
3841 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3844 case OP_ATOMIC_CAS_I4:
3845 case OP_ATOMIC_CAS_I8: {
3846 LLVMValueRef args [3], val;
3849 if (ins->opcode == OP_ATOMIC_CAS_I4)
3850 t = LLVMInt32Type ();
3852 t = LLVMInt64Type ();
3854 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3856 args [1] = convert (ctx, values [ins->sreg3], t);
3858 args [2] = convert (ctx, values [ins->sreg2], t);
3859 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3860 /* cmpxchg returns a pair */
3861 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3864 case OP_MEMORY_BARRIER: {
3865 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3868 case OP_ATOMIC_LOAD_I1:
3869 case OP_ATOMIC_LOAD_I2:
3870 case OP_ATOMIC_LOAD_I4:
3871 case OP_ATOMIC_LOAD_I8:
3872 case OP_ATOMIC_LOAD_U1:
3873 case OP_ATOMIC_LOAD_U2:
3874 case OP_ATOMIC_LOAD_U4:
3875 case OP_ATOMIC_LOAD_U8:
3876 case OP_ATOMIC_LOAD_R4:
3877 case OP_ATOMIC_LOAD_R8: {
3878 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3881 gboolean sext, zext;
3883 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3884 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3885 LLVMValueRef index, addr;
3887 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3892 if (ins->inst_offset != 0) {
3893 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3894 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3899 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3901 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3904 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3906 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3909 case OP_ATOMIC_STORE_I1:
3910 case OP_ATOMIC_STORE_I2:
3911 case OP_ATOMIC_STORE_I4:
3912 case OP_ATOMIC_STORE_I8:
3913 case OP_ATOMIC_STORE_U1:
3914 case OP_ATOMIC_STORE_U2:
3915 case OP_ATOMIC_STORE_U4:
3916 case OP_ATOMIC_STORE_U8:
3917 case OP_ATOMIC_STORE_R4:
3918 case OP_ATOMIC_STORE_R8: {
3919 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3922 gboolean sext, zext;
3924 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3925 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3926 LLVMValueRef index, addr, value;
3928 if (!values [ins->inst_destbasereg])
3929 LLVM_FAILURE (ctx, "inst_destbasereg");
3931 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3933 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3934 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3935 value = convert (ctx, values [ins->sreg1], t);
3937 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3940 case OP_RELAXED_NOP: {
3941 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3942 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3949 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3951 // 257 == FS segment register
3952 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3954 // 256 == GS segment register
3955 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3958 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3959 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3960 /* See mono_amd64_emit_tls_get () */
3961 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3963 // 256 == GS segment register
3964 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3965 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3967 LLVM_FAILURE (ctx, "opcode tls-get");
3972 case OP_TLS_GET_REG: {
3973 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3974 /* See emit_tls_get_reg () */
3975 // 256 == GS segment register
3976 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3977 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3979 LLVM_FAILURE (ctx, "opcode tls-get");
3988 case OP_IADD_OVF_UN:
3990 case OP_ISUB_OVF_UN:
3992 case OP_IMUL_OVF_UN:
3993 #if SIZEOF_VOID_P == 8
3995 case OP_LADD_OVF_UN:
3997 case OP_LSUB_OVF_UN:
3999 case OP_LMUL_OVF_UN:
4002 LLVMValueRef args [2], val, ovf, func;
4004 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4005 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4006 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4008 val = LLVMBuildCall (builder, func, args, 2, "");
4009 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4010 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4011 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4012 CHECK_FAILURE (ctx);
4013 builder = ctx->builder;
4019 * We currently model them using arrays. Promotion to local vregs is
4020 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4021 * so we always have an entry in cfg->varinfo for them.
4022 * FIXME: Is this needed ?
4025 MonoClass *klass = ins->klass;
4026 LLVMValueRef args [5];
4030 LLVM_FAILURE (ctx, "!klass");
4034 if (!addresses [ins->dreg])
4035 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4036 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4037 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4038 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4040 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4041 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4042 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4045 case OP_DUMMY_VZERO:
4048 case OP_STOREV_MEMBASE:
4049 case OP_LOADV_MEMBASE:
4051 MonoClass *klass = ins->klass;
4052 LLVMValueRef src = NULL, dst, args [5];
4053 gboolean done = FALSE;
4057 LLVM_FAILURE (ctx, "!klass");
4061 if (mini_is_gsharedvt_klass (cfg, klass)) {
4063 LLVM_FAILURE (ctx, "gsharedvt");
4067 switch (ins->opcode) {
4068 case OP_STOREV_MEMBASE:
4069 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4070 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4071 /* Decomposed earlier */
4072 g_assert_not_reached ();
4075 if (!addresses [ins->sreg1]) {
4077 g_assert (values [ins->sreg1]);
4078 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));
4079 LLVMBuildStore (builder, values [ins->sreg1], dst);
4082 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4083 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4086 case OP_LOADV_MEMBASE:
4087 if (!addresses [ins->dreg])
4088 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4089 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4090 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4093 if (!addresses [ins->sreg1])
4094 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4095 if (!addresses [ins->dreg])
4096 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4097 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4098 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4101 g_assert_not_reached ();
4103 CHECK_FAILURE (ctx);
4110 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4111 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4113 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4114 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4115 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4118 case OP_LLVM_OUTARG_VT:
4119 if (!addresses [ins->sreg1]) {
4120 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4121 g_assert (values [ins->sreg1]);
4122 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4124 addresses [ins->dreg] = addresses [ins->sreg1];
4130 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4132 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4135 case OP_LOADX_MEMBASE: {
4136 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4139 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4140 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4143 case OP_STOREX_MEMBASE: {
4144 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4147 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4148 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4155 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4159 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4165 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4169 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4173 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4177 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4180 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4183 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4186 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4190 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4201 LLVMValueRef v = NULL;
4203 switch (ins->opcode) {
4208 t = LLVMVectorType (LLVMInt32Type (), 4);
4209 rt = LLVMVectorType (LLVMFloatType (), 4);
4215 t = LLVMVectorType (LLVMInt64Type (), 2);
4216 rt = LLVMVectorType (LLVMDoubleType (), 2);
4219 t = LLVMInt32Type ();
4220 rt = LLVMInt32Type ();
4221 g_assert_not_reached ();
4224 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4225 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4226 switch (ins->opcode) {
4229 v = LLVMBuildAnd (builder, lhs, rhs, "");
4233 v = LLVMBuildOr (builder, lhs, rhs, "");
4237 v = LLVMBuildXor (builder, lhs, rhs, "");
4241 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4244 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4268 case OP_PADDB_SAT_UN:
4269 case OP_PADDW_SAT_UN:
4270 case OP_PSUBB_SAT_UN:
4271 case OP_PSUBW_SAT_UN:
4279 case OP_PMULW_HIGH_UN: {
4280 LLVMValueRef args [2];
4285 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4292 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4296 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4304 case OP_EXTRACTX_U2:
4306 case OP_EXTRACT_U1: {
4308 gboolean zext = FALSE;
4310 t = simd_op_to_llvm_type (ins->opcode);
4312 switch (ins->opcode) {
4320 case OP_EXTRACTX_U2:
4325 t = LLVMInt32Type ();
4326 g_assert_not_reached ();
4329 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4330 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4332 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4341 case OP_EXPAND_R8: {
4342 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4343 LLVMValueRef mask [16], v;
4346 for (i = 0; i < 16; ++i)
4347 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4349 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4351 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4352 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4357 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4360 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4363 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4366 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4369 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4372 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4383 case OP_EXTRACT_MASK:
4390 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4392 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4398 LLVMValueRef args [3];
4402 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4404 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4409 /* This is only used for implementing shifts by non-immediate */
4410 values [ins->dreg] = lhs;
4421 LLVMValueRef args [3];
4424 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4426 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4437 case OP_PSHLQ_REG: {
4438 LLVMValueRef args [3];
4441 args [1] = values [ins->sreg2];
4443 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4450 case OP_PSHUFLEW_LOW:
4451 case OP_PSHUFLEW_HIGH: {
4453 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4454 int i, mask_size = 0;
4455 int imask = ins->inst_c0;
4457 /* Convert the x86 shuffle mask to LLVM's */
4458 switch (ins->opcode) {
4461 mask [0] = ((imask >> 0) & 3);
4462 mask [1] = ((imask >> 2) & 3);
4463 mask [2] = ((imask >> 4) & 3) + 4;
4464 mask [3] = ((imask >> 6) & 3) + 4;
4465 v1 = values [ins->sreg1];
4466 v2 = values [ins->sreg2];
4470 mask [0] = ((imask >> 0) & 1);
4471 mask [1] = ((imask >> 1) & 1) + 2;
4472 v1 = values [ins->sreg1];
4473 v2 = values [ins->sreg2];
4475 case OP_PSHUFLEW_LOW:
4477 mask [0] = ((imask >> 0) & 3);
4478 mask [1] = ((imask >> 2) & 3);
4479 mask [2] = ((imask >> 4) & 3);
4480 mask [3] = ((imask >> 6) & 3);
4485 v1 = values [ins->sreg1];
4486 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4488 case OP_PSHUFLEW_HIGH:
4494 mask [4] = 4 + ((imask >> 0) & 3);
4495 mask [5] = 4 + ((imask >> 2) & 3);
4496 mask [6] = 4 + ((imask >> 4) & 3);
4497 mask [7] = 4 + ((imask >> 6) & 3);
4498 v1 = values [ins->sreg1];
4499 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4503 mask [0] = ((imask >> 0) & 3);
4504 mask [1] = ((imask >> 2) & 3);
4505 mask [2] = ((imask >> 4) & 3);
4506 mask [3] = ((imask >> 6) & 3);
4507 v1 = values [ins->sreg1];
4508 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4511 g_assert_not_reached ();
4513 for (i = 0; i < mask_size; ++i)
4514 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4516 values [ins->dreg] =
4517 LLVMBuildShuffleVector (builder, v1, v2,
4518 LLVMConstVector (mask_values, mask_size), dname);
4522 case OP_UNPACK_LOWB:
4523 case OP_UNPACK_LOWW:
4524 case OP_UNPACK_LOWD:
4525 case OP_UNPACK_LOWQ:
4526 case OP_UNPACK_LOWPS:
4527 case OP_UNPACK_LOWPD:
4528 case OP_UNPACK_HIGHB:
4529 case OP_UNPACK_HIGHW:
4530 case OP_UNPACK_HIGHD:
4531 case OP_UNPACK_HIGHQ:
4532 case OP_UNPACK_HIGHPS:
4533 case OP_UNPACK_HIGHPD: {
4535 LLVMValueRef mask_values [16];
4536 int i, mask_size = 0;
4537 gboolean low = FALSE;
4539 switch (ins->opcode) {
4540 case OP_UNPACK_LOWB:
4544 case OP_UNPACK_LOWW:
4548 case OP_UNPACK_LOWD:
4549 case OP_UNPACK_LOWPS:
4553 case OP_UNPACK_LOWQ:
4554 case OP_UNPACK_LOWPD:
4558 case OP_UNPACK_HIGHB:
4561 case OP_UNPACK_HIGHW:
4564 case OP_UNPACK_HIGHD:
4565 case OP_UNPACK_HIGHPS:
4568 case OP_UNPACK_HIGHQ:
4569 case OP_UNPACK_HIGHPD:
4573 g_assert_not_reached ();
4577 for (i = 0; i < (mask_size / 2); ++i) {
4579 mask [(i * 2) + 1] = mask_size + i;
4582 for (i = 0; i < (mask_size / 2); ++i) {
4583 mask [(i * 2)] = (mask_size / 2) + i;
4584 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4588 for (i = 0; i < mask_size; ++i)
4589 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4591 values [ins->dreg] =
4592 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4593 LLVMConstVector (mask_values, mask_size), dname);
4598 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4599 LLVMValueRef v, val;
4601 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4602 val = LLVMConstNull (t);
4603 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4604 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4606 values [ins->dreg] = val;
4610 case OP_DUPPS_HIGH: {
4611 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4612 LLVMValueRef v1, v2, val;
4615 if (ins->opcode == OP_DUPPS_LOW) {
4616 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4617 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4619 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4620 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4622 val = LLVMConstNull (t);
4623 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4624 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4625 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4626 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4628 values [ins->dreg] = val;
4638 * EXCEPTION HANDLING
4640 case OP_IMPLICIT_EXCEPTION:
4641 /* This marks a place where an implicit exception can happen */
4642 if (bb->region != -1)
4643 LLVM_FAILURE (ctx, "implicit-exception");
4647 MonoMethodSignature *throw_sig;
4648 LLVMValueRef callee, arg;
4649 gboolean rethrow = (ins->opcode == OP_RETHROW);
4650 const char *icall_name;
4652 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4653 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4656 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4657 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4658 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4659 if (cfg->compile_aot) {
4660 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4662 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4666 * LLVM doesn't push the exception argument, so we need a different
4669 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4671 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4675 mono_memory_barrier ();
4677 ctx->lmodule->rethrow = callee;
4679 ctx->lmodule->throw = callee;
4681 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4682 emit_call (ctx, bb, &builder, callee, &arg, 1);
4685 case OP_CALL_HANDLER: {
4687 * We don't 'call' handlers, but instead simply branch to them.
4688 * The code generated by ENDFINALLY will branch back to us.
4690 LLVMBasicBlockRef noex_bb;
4692 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4694 bb_list = info->call_handler_return_bbs;
4697 * Set the indicator variable for the finally clause.
4699 lhs = info->finally_ind;
4701 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4703 /* Branch to the finally clause */
4704 LLVMBuildBr (builder, info->call_handler_target_bb);
4706 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4707 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4709 builder = ctx->builder = create_builder (ctx);
4710 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4712 bblocks [bb->block_num].end_bblock = noex_bb;
4715 case OP_START_HANDLER: {
4718 case OP_ENDFINALLY: {
4719 LLVMBasicBlockRef resume_bb;
4720 MonoBasicBlock *handler_bb;
4721 LLVMValueRef val, switch_ins, callee;
4725 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4726 g_assert (handler_bb);
4727 info = &bblocks [handler_bb->block_num];
4728 lhs = info->finally_ind;
4731 bb_list = info->call_handler_return_bbs;
4733 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4735 /* Load the finally variable */
4736 val = LLVMBuildLoad (builder, lhs, "");
4738 /* Reset the variable */
4739 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4741 /* Branch to either resume_bb, or to the bblocks in bb_list */
4742 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4744 * The other targets are added at the end to handle OP_CALL_HANDLER
4745 * opcodes processed later.
4747 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4749 builder = ctx->builder = create_builder (ctx);
4750 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4752 if (ctx->cfg->compile_aot) {
4753 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4755 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4757 LLVMBuildCall (builder, callee, NULL, 0, "");
4759 LLVMBuildUnreachable (builder);
4760 has_terminator = TRUE;
4766 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4767 LLVM_FAILURE (ctx, reason);
4772 /* Convert the value to the type required by phi nodes */
4773 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4774 if (!values [ins->dreg])
4776 values [ins->dreg] = addresses [ins->dreg];
4778 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4781 /* Add stores for volatile variables */
4782 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4783 emit_volatile_store (ctx, ins->dreg);
4786 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4787 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4789 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4790 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4791 LLVMBuildRetVoid (builder);
4794 if (bb == cfg->bb_entry)
4795 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4804 * mono_llvm_check_method_supported:
4806 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4807 * compiling a method twice.
4810 mono_llvm_check_method_supported (MonoCompile *cfg)
4814 if (cfg->method->save_lmf) {
4815 cfg->exception_message = g_strdup ("lmf");
4816 cfg->disable_llvm = TRUE;
4818 if (cfg->disable_llvm)
4822 * Nested clauses where one of the clauses is a finally clause is
4823 * not supported, because LLVM can't figure out the control flow,
4824 * probably because we resume exception handling by calling our
4825 * own function instead of using the 'resume' llvm instruction.
4827 for (i = 0; i < cfg->header->num_clauses; ++i) {
4828 for (j = 0; j < cfg->header->num_clauses; ++j) {
4829 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4830 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4832 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4833 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4834 cfg->exception_message = g_strdup ("nested clauses");
4835 cfg->disable_llvm = TRUE;
4840 if (cfg->disable_llvm)
4844 if (cfg->method->dynamic) {
4845 cfg->exception_message = g_strdup ("dynamic.");
4846 cfg->disable_llvm = TRUE;
4848 if (cfg->disable_llvm)
4853 * mono_llvm_emit_method:
4855 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4858 mono_llvm_emit_method (MonoCompile *cfg)
4861 MonoMethodSignature *sig;
4863 LLVMTypeRef method_type;
4864 LLVMValueRef method = NULL;
4866 LLVMValueRef *values;
4867 int i, max_block_num, bb_index;
4868 gboolean last = FALSE;
4869 GPtrArray *phi_values;
4870 LLVMCallInfo *linfo;
4872 LLVMModuleRef module;
4874 GPtrArray *bblock_list;
4875 MonoMethodHeader *header;
4876 MonoExceptionClause *clause;
4880 /* The code below might acquire the loader lock, so use it for global locking */
4881 mono_loader_lock ();
4883 /* Used to communicate with the callbacks */
4884 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4886 ctx = g_new0 (EmitContext, 1);
4888 ctx->mempool = cfg->mempool;
4891 * This maps vregs to the LLVM instruction defining them
4893 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4895 * This maps vregs for volatile variables to the LLVM instruction defining their
4898 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4899 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4900 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4901 phi_values = g_ptr_array_sized_new (256);
4903 * This signals whenever the vreg was defined by a phi node with no input vars
4904 * (i.e. all its input bblocks end with NOT_REACHABLE).
4906 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4907 /* Whenever the bblock is unreachable */
4908 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4910 bblock_list = g_ptr_array_sized_new (256);
4912 ctx->values = values;
4913 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4914 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4916 if (cfg->compile_aot) {
4917 ctx->lmodule = &aot_module;
4918 method_name = mono_aot_get_method_name (cfg);
4919 cfg->llvm_method_name = g_strdup (method_name);
4921 init_jit_module (cfg->domain);
4922 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4923 method_name = mono_method_full_name (cfg->method, TRUE);
4926 module = ctx->module = ctx->lmodule->module;
4929 LLVM_FAILURE (ctx, "gsharedvt");
4933 static int count = 0;
4936 if (g_getenv ("LLVM_COUNT")) {
4937 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4938 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4942 if (count > atoi (g_getenv ("LLVM_COUNT")))
4943 LLVM_FAILURE (ctx, "");
4948 sig = mono_method_signature (cfg->method);
4951 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4953 CHECK_FAILURE (ctx);
4956 linfo->rgctx_arg = TRUE;
4957 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4958 CHECK_FAILURE (ctx);
4961 * This maps parameter indexes in the original signature to the indexes in
4962 * the LLVM signature.
4964 ctx->pindexes = sinfo.pindexes;
4966 method = LLVMAddFunction (module, method_name, method_type);
4967 ctx->lmethod = method;
4969 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4970 LLVMSetLinkage (method, LLVMPrivateLinkage);
4972 LLVMAddFunctionAttr (method, LLVMUWTable);
4974 if (cfg->compile_aot) {
4975 LLVMSetLinkage (method, LLVMInternalLinkage);
4976 if (ctx->lmodule->external_symbols) {
4977 LLVMSetLinkage (method, LLVMExternalLinkage);
4978 LLVMSetVisibility (method, LLVMHiddenVisibility);
4981 LLVMSetLinkage (method, LLVMPrivateLinkage);
4984 if (cfg->method->save_lmf)
4985 LLVM_FAILURE (ctx, "lmf");
4987 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4988 LLVM_FAILURE (ctx, "pinvoke signature");
4990 header = cfg->header;
4991 for (i = 0; i < header->num_clauses; ++i) {
4992 clause = &header->clauses [i];
4993 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4994 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4996 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
4997 /* We can't handle inlined methods with clauses */
4998 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5000 if (linfo->rgctx_arg) {
5001 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5003 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5004 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5005 * CC_X86_64_Mono in X86CallingConv.td.
5007 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5008 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5010 if (cfg->vret_addr) {
5011 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5012 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5015 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5016 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5019 names = g_new (char *, sig->param_count);
5020 mono_method_get_param_names (cfg->method, (const char **) names);
5022 for (i = 0; i < sig->param_count; ++i) {
5025 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5026 if (names [i] && names [i][0] != '\0')
5027 name = g_strdup_printf ("arg_%s", names [i]);
5029 name = g_strdup_printf ("arg_%d", i);
5030 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5032 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5033 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5037 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5038 ctx->minfo = mono_debug_lookup_method (cfg->method);
5039 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5043 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5044 max_block_num = MAX (max_block_num, bb->block_num);
5045 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5047 /* Add branches between non-consecutive bblocks */
5048 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5049 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5050 bb->next_bb != bb->last_ins->inst_false_bb) {
5052 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5053 inst->opcode = OP_BR;
5054 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5055 mono_bblock_add_inst (bb, inst);
5060 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5061 * was later optimized away, so clear these flags, and add them back for the still
5062 * present OP_LDADDR instructions.
5064 for (i = 0; i < cfg->next_vreg; ++i) {
5067 ins = get_vreg_to_inst (cfg, i);
5068 if (ins && ins != cfg->rgctx_var)
5069 ins->flags &= ~MONO_INST_INDIRECT;
5073 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5075 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5077 LLVMBuilderRef builder;
5079 char dname_buf[128];
5081 builder = create_builder (ctx);
5083 for (ins = bb->code; ins; ins = ins->next) {
5084 switch (ins->opcode) {
5089 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5091 CHECK_FAILURE (ctx);
5093 if (ins->opcode == OP_VPHI) {
5094 /* Treat valuetype PHI nodes as operating on the address itself */
5095 g_assert (ins->klass);
5096 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5100 * Have to precreate these, as they can be referenced by
5101 * earlier instructions.
5103 sprintf (dname_buf, "t%d", ins->dreg);
5105 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5107 if (ins->opcode == OP_VPHI)
5108 ctx->addresses [ins->dreg] = values [ins->dreg];
5110 g_ptr_array_add (phi_values, values [ins->dreg]);
5113 * Set the expected type of the incoming arguments since these have
5114 * to have the same type.
5116 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5117 int sreg1 = ins->inst_phi_args [i + 1];
5120 ctx->vreg_types [sreg1] = phi_type;
5125 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5134 * Create an ordering for bblocks, use the depth first order first, then
5135 * put the exception handling bblocks last.
5137 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5138 bb = cfg->bblocks [bb_index];
5139 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5140 g_ptr_array_add (bblock_list, bb);
5141 bblocks [bb->block_num].added = TRUE;
5145 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5146 if (!bblocks [bb->block_num].added)
5147 g_ptr_array_add (bblock_list, bb);
5151 * Second pass: generate code.
5153 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5154 bb = g_ptr_array_index (bblock_list, bb_index);
5156 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5159 process_bb (ctx, bb);
5160 CHECK_FAILURE (ctx);
5163 /* Add incoming phi values */
5164 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5165 GSList *l, *ins_list;
5167 ins_list = bblocks [bb->block_num].phi_nodes;
5169 for (l = ins_list; l; l = l->next) {
5170 PhiNode *node = l->data;
5171 MonoInst *phi = node->phi;
5172 int sreg1 = node->sreg;
5173 LLVMBasicBlockRef in_bb;
5178 in_bb = get_end_bb (ctx, node->in_bb);
5180 if (ctx->unreachable [node->in_bb->block_num])
5183 if (!values [sreg1])
5184 /* Can happen with values in EH clauses */
5185 LLVM_FAILURE (ctx, "incoming phi sreg1");
5187 if (phi->opcode == OP_VPHI) {
5188 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5189 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5191 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5193 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5194 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5195 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5200 /* Create the SWITCH statements for ENDFINALLY instructions */
5201 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5202 BBInfo *info = &bblocks [bb->block_num];
5204 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5205 LLVMValueRef switch_ins = l->data;
5206 GSList *bb_list = info->call_handler_return_bbs;
5208 for (i = 0; i < g_slist_length (bb_list); ++i)
5209 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5213 if (cfg->verbose_level > 1)
5214 mono_llvm_dump_value (method);
5216 if (cfg->compile_aot)
5217 mark_as_used (ctx->lmodule, method);
5219 if (cfg->compile_aot) {
5220 LLVMValueRef md_args [16];
5221 LLVMValueRef md_node;
5224 method_index = mono_aot_get_method_index (cfg->orig_method);
5225 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5226 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5227 md_node = LLVMMDNode (md_args, 2);
5228 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5229 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5232 if (cfg->compile_aot) {
5233 /* Don't generate native code, keep the LLVM IR */
5234 if (cfg->compile_aot && cfg->verbose_level)
5235 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5237 //LLVMVerifyFunction(method, 0);
5239 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5241 if (cfg->verbose_level > 1)
5242 mono_llvm_dump_value (method);
5244 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5246 /* Set by emit_cb */
5247 g_assert (cfg->code_len);
5249 /* FIXME: Free the LLVM IL for the function */
5252 if (ctx->lmodule->method_to_lmethod)
5253 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5260 /* Need to add unused phi nodes as they can be referenced by other values */
5261 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5262 LLVMBuilderRef builder;
5264 builder = create_builder (ctx);
5265 LLVMPositionBuilderAtEnd (builder, phi_bb);
5267 for (i = 0; i < phi_values->len; ++i) {
5268 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5269 if (LLVMGetInstructionParent (v) == NULL)
5270 LLVMInsertIntoBuilder (builder, v);
5273 LLVMDeleteFunction (method);
5278 g_free (ctx->addresses);
5279 g_free (ctx->vreg_types);
5280 g_free (ctx->vreg_cli_types);
5281 g_free (ctx->pindexes);
5282 g_free (ctx->is_dead);
5283 g_free (ctx->unreachable);
5284 g_ptr_array_free (phi_values, TRUE);
5285 g_free (ctx->bblocks);
5286 g_hash_table_destroy (ctx->region_to_handler);
5287 g_hash_table_destroy (ctx->clause_to_handler);
5288 g_free (method_name);
5289 g_ptr_array_free (bblock_list, TRUE);
5291 for (l = ctx->builders; l; l = l->next) {
5292 LLVMBuilderRef builder = l->data;
5293 LLVMDisposeBuilder (builder);
5298 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5300 mono_loader_unlock ();
5304 * mono_llvm_emit_call:
5306 * Same as mono_arch_emit_call () for LLVM.
5309 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5312 MonoMethodSignature *sig;
5313 int i, n, stack_size;
5318 sig = call->signature;
5319 n = sig->param_count + sig->hasthis;
5321 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5323 if (cfg->disable_llvm)
5326 if (sig->call_convention == MONO_CALL_VARARG) {
5327 cfg->exception_message = g_strdup ("varargs");
5328 cfg->disable_llvm = TRUE;
5331 for (i = 0; i < n; ++i) {
5334 ainfo = call->cinfo->args + i;
5336 in = call->args [i];
5338 /* Simply remember the arguments */
5339 switch (ainfo->storage) {
5341 case LLVMArgInFPReg: {
5342 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5345 opcode = mono_type_to_regmove (cfg, t);
5346 if (opcode == OP_FMOVE) {
5347 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5348 ins->dreg = mono_alloc_freg (cfg);
5349 } else if (opcode == OP_LMOVE) {
5350 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5351 ins->dreg = mono_alloc_lreg (cfg);
5353 MONO_INST_NEW (cfg, ins, OP_MOVE);
5354 ins->dreg = mono_alloc_ireg (cfg);
5356 ins->sreg1 = in->dreg;
5359 case LLVMArgVtypeByVal:
5360 case LLVMArgVtypeInReg:
5361 case LLVMArgAsIArgs:
5362 case LLVMArgAsFpArgs:
5363 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5364 ins->dreg = mono_alloc_ireg (cfg);
5365 ins->sreg1 = in->dreg;
5366 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5369 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5370 cfg->exception_message = g_strdup ("ainfo->storage");
5371 cfg->disable_llvm = TRUE;
5375 if (!cfg->disable_llvm) {
5376 MONO_ADD_INS (cfg->cbb, ins);
5377 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5382 static unsigned char*
5383 alloc_cb (LLVMValueRef function, int size)
5387 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5391 return mono_domain_code_reserve (cfg->domain, size);
5393 return mono_domain_code_reserve (mono_domain_get (), size);
5398 emitted_cb (LLVMValueRef function, void *start, void *end)
5402 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5404 cfg->code_len = (guint8*)end - (guint8*)start;
5408 exception_cb (void *data)
5411 MonoJitExceptionInfo *ei;
5412 guint32 ei_len, i, j, nested_len, nindex;
5413 gpointer *type_info;
5414 int this_reg, this_offset;
5416 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5420 * data points to a DWARF FDE structure, convert it to our unwind format and
5422 * An alternative would be to save it directly, and modify our unwinder to work
5425 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);
5426 if (cfg->verbose_level > 1)
5427 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5429 /* Count nested clauses */
5431 for (i = 0; i < ei_len; ++i) {
5432 for (j = 0; j < ei_len; ++j) {
5433 gint32 cindex1 = *(gint32*)type_info [i];
5434 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5435 gint32 cindex2 = *(gint32*)type_info [j];
5436 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5438 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5444 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5445 cfg->llvm_ex_info_len = ei_len + nested_len;
5446 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5447 /* Fill the rest of the information from the type info */
5448 for (i = 0; i < ei_len; ++i) {
5449 gint32 clause_index = *(gint32*)type_info [i];
5450 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5452 cfg->llvm_ex_info [i].flags = clause->flags;
5453 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5454 cfg->llvm_ex_info [i].clause_index = clause_index;
5458 * For nested clauses, the LLVM produced exception info associates the try interval with
5459 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5460 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5461 * and everything else from the nested clause.
5464 for (i = 0; i < ei_len; ++i) {
5465 for (j = 0; j < ei_len; ++j) {
5466 gint32 cindex1 = *(gint32*)type_info [i];
5467 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5468 gint32 cindex2 = *(gint32*)type_info [j];
5469 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5471 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5472 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5473 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5474 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5475 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5476 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5481 g_assert (nindex == ei_len + nested_len);
5482 cfg->llvm_this_reg = this_reg;
5483 cfg->llvm_this_offset = this_offset;
5485 /* type_info [i] is cfg mempool allocated, no need to free it */
5492 dlsym_cb (const char *name, void **symbol)
5498 if (!strcmp (name, "__bzero")) {
5499 *symbol = (void*)bzero;
5501 current = mono_dl_open (NULL, 0, NULL);
5504 err = mono_dl_symbol (current, name, symbol);
5506 mono_dl_close (current);
5508 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5509 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5515 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5517 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5521 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5523 LLVMTypeRef param_types [4];
5525 param_types [0] = param_type1;
5526 param_types [1] = param_type2;
5528 AddFunc (module, name, ret_type, param_types, 2);
5532 add_intrinsics (LLVMModuleRef module)
5534 /* Emit declarations of instrinsics */
5536 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5537 * type doesn't seem to do any locking.
5540 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5542 memset_param_count = 5;
5543 memset_func_name = "llvm.memset.p0i8.i32";
5545 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5549 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5551 memcpy_param_count = 5;
5552 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5554 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5558 LLVMTypeRef params [] = { LLVMDoubleType () };
5560 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5561 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5562 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5564 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5565 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5569 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5570 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5571 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5573 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5574 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5575 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5576 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5577 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5578 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5579 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5583 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5584 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5585 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5587 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5588 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5589 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5590 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5591 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5592 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5597 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5599 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5602 /* SSE intrinsics */
5603 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5605 LLVMTypeRef ret_type, arg_types [16];
5608 ret_type = type_to_simd_type (MONO_TYPE_I4);
5609 arg_types [0] = ret_type;
5610 arg_types [1] = ret_type;
5611 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5612 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5614 ret_type = type_to_simd_type (MONO_TYPE_I2);
5615 arg_types [0] = ret_type;
5616 arg_types [1] = ret_type;
5617 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5618 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5619 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5620 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5621 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5622 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5623 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5624 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5625 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5626 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5628 ret_type = type_to_simd_type (MONO_TYPE_I1);
5629 arg_types [0] = ret_type;
5630 arg_types [1] = ret_type;
5631 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5633 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5639 ret_type = type_to_simd_type (MONO_TYPE_R8);
5640 arg_types [0] = ret_type;
5641 arg_types [1] = ret_type;
5642 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5643 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5644 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5645 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5648 ret_type = type_to_simd_type (MONO_TYPE_R4);
5649 arg_types [0] = ret_type;
5650 arg_types [1] = ret_type;
5651 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5652 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5653 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5654 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5655 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5658 ret_type = type_to_simd_type (MONO_TYPE_I1);
5659 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5660 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5661 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5662 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5663 ret_type = type_to_simd_type (MONO_TYPE_I2);
5664 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5665 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5666 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5667 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5670 ret_type = type_to_simd_type (MONO_TYPE_R8);
5671 arg_types [0] = ret_type;
5672 arg_types [1] = ret_type;
5673 arg_types [2] = LLVMInt8Type ();
5674 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5675 ret_type = type_to_simd_type (MONO_TYPE_R4);
5676 arg_types [0] = ret_type;
5677 arg_types [1] = ret_type;
5678 arg_types [2] = LLVMInt8Type ();
5679 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5681 /* Conversion ops */
5682 ret_type = type_to_simd_type (MONO_TYPE_R8);
5683 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5684 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5685 ret_type = type_to_simd_type (MONO_TYPE_R4);
5686 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5687 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5688 ret_type = type_to_simd_type (MONO_TYPE_I4);
5689 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5690 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5691 ret_type = type_to_simd_type (MONO_TYPE_I4);
5692 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5693 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5694 ret_type = type_to_simd_type (MONO_TYPE_R4);
5695 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5696 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5697 ret_type = type_to_simd_type (MONO_TYPE_R8);
5698 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5699 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5701 ret_type = type_to_simd_type (MONO_TYPE_I4);
5702 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5703 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5704 ret_type = type_to_simd_type (MONO_TYPE_I4);
5705 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5706 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5709 ret_type = type_to_simd_type (MONO_TYPE_R8);
5710 arg_types [0] = ret_type;
5711 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5712 ret_type = type_to_simd_type (MONO_TYPE_R4);
5713 arg_types [0] = ret_type;
5714 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5715 ret_type = type_to_simd_type (MONO_TYPE_R4);
5716 arg_types [0] = ret_type;
5717 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5718 ret_type = type_to_simd_type (MONO_TYPE_R4);
5719 arg_types [0] = ret_type;
5720 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5723 ret_type = type_to_simd_type (MONO_TYPE_I2);
5724 arg_types [0] = ret_type;
5725 arg_types [1] = LLVMInt32Type ();
5726 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5727 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5728 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5729 ret_type = type_to_simd_type (MONO_TYPE_I4);
5730 arg_types [0] = ret_type;
5731 arg_types [1] = LLVMInt32Type ();
5732 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5733 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5734 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5735 ret_type = type_to_simd_type (MONO_TYPE_I8);
5736 arg_types [0] = ret_type;
5737 arg_types [1] = LLVMInt32Type ();
5738 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5739 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5742 ret_type = LLVMInt32Type ();
5743 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5744 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5747 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5750 /* Load/Store intrinsics */
5752 LLVMTypeRef arg_types [5];
5756 for (i = 1; i <= 8; i *= 2) {
5757 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5758 arg_types [1] = LLVMInt32Type ();
5759 arg_types [2] = LLVMInt1Type ();
5760 arg_types [3] = LLVMInt32Type ();
5761 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5762 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5764 arg_types [0] = LLVMIntType (i * 8);
5765 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5766 arg_types [2] = LLVMInt32Type ();
5767 arg_types [3] = LLVMInt1Type ();
5768 arg_types [4] = LLVMInt32Type ();
5769 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5770 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5776 add_types (MonoLLVMModule *lmodule)
5778 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5782 mono_llvm_init (void)
5784 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5788 init_jit_module (MonoDomain *domain)
5790 MonoJitICallInfo *info;
5791 MonoJitDomainInfo *dinfo;
5792 MonoLLVMModule *module;
5795 dinfo = domain_jit_info (domain);
5796 if (dinfo->llvm_module)
5799 mono_loader_lock ();
5801 if (dinfo->llvm_module) {
5802 mono_loader_unlock ();
5806 module = g_new0 (MonoLLVMModule, 1);
5808 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5809 module->module = LLVMModuleCreateWithName (name);
5811 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5813 add_intrinsics (module->module);
5816 module->llvm_types = g_hash_table_new (NULL, NULL);
5818 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5820 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5822 mono_memory_barrier ();
5824 dinfo->llvm_module = module;
5826 mono_loader_unlock ();
5830 mono_llvm_cleanup (void)
5832 if (aot_module.module)
5833 LLVMDisposeModule (aot_module.module);
5835 LLVMContextDispose (LLVMGetGlobalContext ());
5839 mono_llvm_free_domain_info (MonoDomain *domain)
5841 MonoJitDomainInfo *info = domain_jit_info (domain);
5842 MonoLLVMModule *module = info->llvm_module;
5848 if (module->llvm_types)
5849 g_hash_table_destroy (module->llvm_types);
5851 mono_llvm_dispose_ee (module->mono_ee);
5853 if (module->bb_names) {
5854 for (i = 0; i < module->bb_names_len; ++i)
5855 g_free (module->bb_names [i]);
5856 g_free (module->bb_names);
5858 //LLVMDisposeModule (module->module);
5862 info->llvm_module = NULL;
5866 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5868 /* Delete previous module */
5869 if (aot_module.plt_entries)
5870 g_hash_table_destroy (aot_module.plt_entries);
5871 if (aot_module.module)
5872 LLVMDisposeModule (aot_module.module);
5874 memset (&aot_module, 0, sizeof (aot_module));
5876 aot_module.module = LLVMModuleCreateWithName ("aot");
5877 aot_module.got_symbol = got_symbol;
5878 aot_module.external_symbols = external_symbols;
5879 aot_module.emit_dwarf = emit_dwarf;
5880 /* The first few entries are reserved */
5881 aot_module.max_got_offset = 16;
5883 add_intrinsics (aot_module.module);
5884 add_types (&aot_module);
5888 * We couldn't compute the type of the LLVM global representing the got because
5889 * its size is only known after all the methods have been emitted. So create
5890 * a dummy variable, and replace all uses it with the real got variable when
5891 * its size is known in mono_llvm_emit_aot_module ().
5894 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5896 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5897 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5900 /* Add a dummy personality function */
5902 LLVMBasicBlockRef lbb;
5903 LLVMBuilderRef lbuilder;
5904 LLVMValueRef personality;
5906 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5907 LLVMSetLinkage (personality, LLVMInternalLinkage);
5908 lbb = LLVMAppendBasicBlock (personality, "BB0");
5909 lbuilder = LLVMCreateBuilder ();
5910 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5911 LLVMBuildRetVoid (lbuilder);
5912 mark_as_used (&aot_module, personality);
5915 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5916 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5917 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5918 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5922 * Emit the aot module into the LLVM bitcode file FILENAME.
5925 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5927 LLVMTypeRef got_type;
5928 LLVMValueRef real_got;
5929 MonoLLVMModule *module = &aot_module;
5932 * Create the real got variable and replace all uses of the dummy variable with
5935 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5936 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5937 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5938 if (module->external_symbols) {
5939 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5940 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5942 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5944 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5946 mark_as_used (&aot_module, real_got);
5948 /* Delete the dummy got so it doesn't become a global */
5949 LLVMDeleteGlobal (aot_module.got_var);
5951 emit_llvm_used (&aot_module);
5952 emit_dbg_info (&aot_module, filename, cu_name);
5954 /* Replace PLT entries for directly callable methods with the methods themselves */
5956 GHashTableIter iter;
5958 LLVMValueRef callee;
5960 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5961 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5962 if (mono_aot_is_direct_callable (ji)) {
5963 LLVMValueRef lmethod;
5965 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5966 /* The types might not match because the caller might pass an rgctx */
5967 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
5968 mono_llvm_replace_uses_of (callee, lmethod);
5969 mono_aot_mark_unused_llvm_plt_entry (ji);
5979 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5980 g_assert_not_reached ();
5985 LLVMWriteBitcodeToFile (aot_module.module, filename);
5990 md_string (const char *s)
5992 return LLVMMDString (s, strlen (s));
5995 /* Debugging support */
5998 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6000 LLVMModuleRef module = lmodule->module;
6001 LLVMValueRef args [16], cu_args [16], cu, ver;
6003 char *build_info, *s, *dir;
6006 * This can only be enabled when LLVM code is emitted into a separate object
6007 * file, since the AOT compiler also emits dwarf info,
6008 * and the abbrev indexes will not be correct since llvm has added its own
6011 if (!lmodule->emit_dwarf)
6015 * Emit dwarf info in the form of LLVM metadata. There is some
6016 * out-of-date documentation at:
6017 * http://llvm.org/docs/SourceLevelDebugging.html
6018 * but most of this was gathered from the llvm and
6023 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6024 /* CU name/compilation dir */
6025 dir = g_path_get_dirname (filename);
6026 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6027 args [1] = LLVMMDString (dir, strlen (dir));
6028 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6031 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6033 build_info = mono_get_runtime_build_info ();
6034 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6035 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6036 g_free (build_info);
6038 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6040 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6041 /* Runtime version */
6042 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6044 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6045 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6047 if (lmodule->subprogram_mds) {
6051 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6052 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6053 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6054 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6056 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6059 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6060 /* Imported modules */
6061 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6063 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6064 /* DebugEmissionKind = FullDebug */
6065 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6066 cu = LLVMMDNode (cu_args, n_cuargs);
6067 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6069 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6070 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6071 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6072 ver = LLVMMDNode (args, 3);
6073 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6075 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6076 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6077 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6078 ver = LLVMMDNode (args, 3);
6079 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6083 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6085 MonoLLVMModule *module = ctx->lmodule;
6086 MonoDebugMethodInfo *minfo = ctx->minfo;
6087 char *source_file, *dir, *filename;
6088 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6089 MonoSymSeqPoint *sym_seq_points;
6095 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6097 source_file = g_strdup ("<unknown>");
6098 dir = g_path_get_dirname (source_file);
6099 filename = g_path_get_basename (source_file);
6101 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6102 args [0] = md_string (filename);
6103 args [1] = md_string (dir);
6104 ctx_args [1] = LLVMMDNode (args, 2);
6105 ctx_md = LLVMMDNode (ctx_args, 2);
6107 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6108 type_args [1] = NULL;
6109 type_args [2] = NULL;
6110 type_args [3] = LLVMMDString ("", 0);
6111 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6112 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6113 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6114 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6115 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6116 type_args [9] = NULL;
6117 type_args [10] = NULL;
6118 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6119 type_args [12] = NULL;
6120 type_args [13] = NULL;
6121 type_args [14] = NULL;
6122 type_md = LLVMMDNode (type_args, 14);
6124 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6125 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6126 /* Source directory + file pair */
6127 args [0] = md_string (filename);
6128 args [1] = md_string (dir);
6129 md_args [1] = LLVMMDNode (args ,2);
6130 md_args [2] = ctx_md;
6131 md_args [3] = md_string (cfg->method->name);
6132 md_args [4] = md_string (name);
6133 md_args [5] = md_string (name);
6136 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6138 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6140 md_args [7] = type_md;
6142 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6144 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6146 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6147 /* Index into a virtual function */
6148 md_args [11] = NULL;
6149 md_args [12] = NULL;
6151 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6153 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6154 /* Pointer to LLVM function */
6155 md_args [15] = method;
6156 /* Function template parameter */
6157 md_args [16] = NULL;
6158 /* Function declaration descriptor */
6159 md_args [17] = NULL;
6160 /* List of function variables */
6161 md_args [18] = LLVMMDNode (args, 0);
6163 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6164 md = LLVMMDNode (md_args, 20);
6166 if (!module->subprogram_mds)
6167 module->subprogram_mds = g_ptr_array_new ();
6168 g_ptr_array_add (module->subprogram_mds, md);
6172 g_free (source_file);
6173 g_free (sym_seq_points);
6179 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6181 MonoCompile *cfg = ctx->cfg;
6183 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6184 MonoDebugSourceLocation *loc;
6185 LLVMValueRef loc_md, md_args [16];
6188 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6192 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6193 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6194 md_args [nmd_args ++] = ctx->dbg_md;
6195 md_args [nmd_args ++] = NULL;
6196 loc_md = LLVMMDNode (md_args, nmd_args);
6197 LLVMSetCurrentDebugLocation (builder, loc_md);
6198 mono_debug_symfile_free_location (loc);
6205 - Emit LLVM IR from the mono IR using the LLVM C API.
6206 - The original arch specific code remains, so we can fall back to it if we run
6207 into something we can't handle.
6211 A partial list of issues:
6212 - Handling of opcodes which can throw exceptions.
6214 In the mono JIT, these are implemented using code like this:
6221 push throw_pos - method
6222 call <exception trampoline>
6224 The problematic part is push throw_pos - method, which cannot be represented
6225 in the LLVM IR, since it does not support label values.
6226 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6227 be implemented in JIT mode ?
6228 -> a possible but slower implementation would use the normal exception
6229 throwing code but it would need to control the placement of the throw code
6230 (it needs to be exactly after the compare+branch).
6231 -> perhaps add a PC offset intrinsics ?
6233 - efficient implementation of .ovf opcodes.
6235 These are currently implemented as:
6236 <ins which sets the condition codes>
6239 Some overflow opcodes are now supported by LLVM SVN.
6241 - exception handling, unwinding.
6242 - SSA is disabled for methods with exception handlers
6243 - How to obtain unwind info for LLVM compiled methods ?
6244 -> this is now solved by converting the unwind info generated by LLVM
6246 - LLVM uses the c++ exception handling framework, while we use our home grown
6247 code, and couldn't use the c++ one:
6248 - its not supported under VC++, other exotic platforms.
6249 - it might be impossible to support filter clauses with it.
6253 The trampolines need a predictable call sequence, since they need to disasm
6254 the calling code to obtain register numbers / offsets.
6256 LLVM currently generates this code in non-JIT mode:
6257 mov -0x98(%rax),%eax
6259 Here, the vtable pointer is lost.
6260 -> solution: use one vtable trampoline per class.
6262 - passing/receiving the IMT pointer/RGCTX.
6263 -> solution: pass them as normal arguments ?
6267 LLVM does not allow the specification of argument registers etc. This means
6268 that all calls are made according to the platform ABI.
6270 - passing/receiving vtypes.
6272 Vtypes passed/received in registers are handled by the front end by using
6273 a signature with scalar arguments, and loading the parts of the vtype into those
6276 Vtypes passed on the stack are handled using the 'byval' attribute.
6280 Supported though alloca, we need to emit the load/store code.
6284 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6285 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6286 This is made easier because the IR is already in SSA form.
6287 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6288 types are frequently used incorrectly.
6293 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6294 it with the file containing the methods emitted by the JIT and the AOT data
6298 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6299 * - each bblock should end with a branch
6300 * - setting the return value, making cfg->ret non-volatile
6301 * - avoid some transformations in the JIT which make it harder for us to generate
6303 * - use pointer types to help optimizations.