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/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
13 #ifndef __STDC_LIMIT_MACROS
14 #define __STDC_LIMIT_MACROS
16 #ifndef __STDC_CONSTANT_MACROS
17 #define __STDC_CONSTANT_MACROS
20 #include "llvm-c/Core.h"
21 #include "llvm-c/ExecutionEngine.h"
22 #include "llvm-c/BitWriter.h"
23 #include "llvm-c/Analysis.h"
25 #include "mini-llvm-cpp.h"
28 * Information associated by mono with LLVM modules.
32 LLVMValueRef throw, rethrow, throw_corlib_exception;
33 GHashTable *llvm_types;
35 const char *got_symbol;
36 GHashTable *plt_entries;
40 * Information associated by the backend with mono basic blocks.
43 LLVMBasicBlockRef bblock, end_bblock;
44 LLVMValueRef finally_ind;
45 gboolean added, invoke_target;
47 * If this bblock is the start of a finally clause, this is a list of bblocks it
48 * needs to branch to in ENDFINALLY.
50 GSList *call_handler_return_bbs;
52 * If this bblock is the start of a finally clause, this is the bblock that
53 * CALL_HANDLER needs to branch to.
55 LLVMBasicBlockRef call_handler_target_bb;
56 /* The list of switch statements generated by ENDFINALLY instructions */
57 GSList *endfinally_switch_ins_list;
62 * Structure containing emit state
67 /* Maps method names to the corresponding LLVMValueRef */
68 GHashTable *emitted_method_decls;
72 MonoLLVMModule *lmodule;
75 int sindex, default_index, ex_index;
76 LLVMBuilderRef builder;
77 LLVMValueRef *values, *addresses;
78 MonoType **vreg_cli_types;
80 MonoMethodSignature *sig;
82 GHashTable *region_to_handler;
83 LLVMBuilderRef alloca_builder;
84 LLVMValueRef last_alloca;
85 LLVMValueRef rgctx_arg;
86 LLVMTypeRef *vreg_types;
88 gboolean *unreachable;
97 MonoBasicBlock *in_bb;
102 * Instruction metadata
103 * This is the same as ins_info, but LREG != IREG.
111 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
112 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
119 /* keep in sync with the enum in mini.h */
122 #include "mini-ops.h"
127 #if SIZEOF_VOID_P == 4
128 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
130 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
133 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
136 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
138 #define TRACE_FAILURE(msg)
142 #define IS_TARGET_X86 1
144 #define IS_TARGET_X86 0
147 #define LLVM_FAILURE(ctx, reason) do { \
148 TRACE_FAILURE (reason); \
149 (ctx)->cfg->exception_message = g_strdup (reason); \
150 (ctx)->cfg->disable_llvm = TRUE; \
154 #define CHECK_FAILURE(ctx) do { \
155 if ((ctx)->cfg->disable_llvm) \
159 static LLVMIntPredicate cond_to_llvm_cond [] = {
172 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
185 static LLVMExecutionEngineRef ee;
186 static MonoNativeTlsKey current_cfg_tls_id;
188 static MonoLLVMModule jit_module, aot_module;
189 static gboolean jit_module_inited;
190 static int memset_param_count, memcpy_param_count;
191 static const char *memset_func_name;
192 static const char *memcpy_func_name;
194 static void init_jit_module (void);
199 * The LLVM type with width == sizeof (gpointer)
204 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
210 * Return the size of the LLVM representation of the vtype T.
213 get_vtype_size (MonoType *t)
217 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
219 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
226 * simd_class_to_llvm_type:
228 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
231 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
233 if (!strcmp (klass->name, "Vector2d")) {
234 return LLVMVectorType (LLVMDoubleType (), 2);
235 } else if (!strcmp (klass->name, "Vector2l")) {
236 return LLVMVectorType (LLVMInt64Type (), 2);
237 } else if (!strcmp (klass->name, "Vector2ul")) {
238 return LLVMVectorType (LLVMInt64Type (), 2);
239 } else if (!strcmp (klass->name, "Vector4i")) {
240 return LLVMVectorType (LLVMInt32Type (), 4);
241 } else if (!strcmp (klass->name, "Vector4ui")) {
242 return LLVMVectorType (LLVMInt32Type (), 4);
243 } else if (!strcmp (klass->name, "Vector4f")) {
244 return LLVMVectorType (LLVMFloatType (), 4);
245 } else if (!strcmp (klass->name, "Vector8s")) {
246 return LLVMVectorType (LLVMInt16Type (), 8);
247 } else if (!strcmp (klass->name, "Vector8us")) {
248 return LLVMVectorType (LLVMInt16Type (), 8);
249 } else if (!strcmp (klass->name, "Vector16sb")) {
250 return LLVMVectorType (LLVMInt8Type (), 16);
251 } else if (!strcmp (klass->name, "Vector16b")) {
252 return LLVMVectorType (LLVMInt8Type (), 16);
254 printf ("%s\n", klass->name);
260 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
261 static inline G_GNUC_UNUSED LLVMTypeRef
262 type_to_simd_type (int type)
266 return LLVMVectorType (LLVMInt8Type (), 16);
268 return LLVMVectorType (LLVMInt16Type (), 8);
270 return LLVMVectorType (LLVMInt32Type (), 4);
272 return LLVMVectorType (LLVMInt64Type (), 2);
274 return LLVMVectorType (LLVMDoubleType (), 2);
276 return LLVMVectorType (LLVMFloatType (), 4);
278 g_assert_not_reached ();
286 * Return the LLVM type corresponding to T.
289 type_to_llvm_type (EmitContext *ctx, MonoType *t)
292 return LLVMPointerType (LLVMInt8Type (), 0);
295 return LLVMVoidType ();
297 return LLVMInt8Type ();
299 return LLVMInt16Type ();
301 return LLVMInt32Type ();
303 return LLVMInt8Type ();
305 return LLVMInt16Type ();
307 return LLVMInt32Type ();
308 case MONO_TYPE_BOOLEAN:
309 return LLVMInt8Type ();
312 return LLVMInt64Type ();
314 return LLVMInt16Type ();
316 return LLVMFloatType ();
318 return LLVMDoubleType ();
321 return IntPtrType ();
322 case MONO_TYPE_OBJECT:
323 case MONO_TYPE_CLASS:
324 case MONO_TYPE_ARRAY:
325 case MONO_TYPE_SZARRAY:
326 case MONO_TYPE_STRING:
328 return IntPtrType ();
331 /* Because of generic sharing */
332 return IntPtrType ();
333 case MONO_TYPE_GENERICINST:
334 if (!mono_type_generic_inst_is_valuetype (t))
335 return IntPtrType ();
337 case MONO_TYPE_VALUETYPE:
338 case MONO_TYPE_TYPEDBYREF: {
342 klass = mono_class_from_mono_type (t);
344 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
345 return simd_class_to_llvm_type (ctx, klass);
348 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
349 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
352 LLVMTypeRef *eltypes;
355 size = get_vtype_size (t);
357 eltypes = g_new (LLVMTypeRef, size);
358 for (i = 0; i < size; ++i)
359 eltypes [i] = LLVMInt8Type ();
361 name = mono_type_full_name (&klass->byval_arg);
362 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
363 LLVMStructSetBody (ltype, eltypes, size, FALSE);
364 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
371 printf ("X: %d\n", t->type);
372 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
373 ctx->cfg->disable_llvm = TRUE;
381 * Return whenever T is an unsigned int type.
384 type_is_unsigned (EmitContext *ctx, MonoType *t)
400 * type_to_llvm_arg_type:
402 * Same as type_to_llvm_type, but treat i8/i16 as i32.
405 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
407 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
409 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
411 * LLVM generates code which only sets the lower bits, while JITted
412 * code expects all the bits to be set.
414 ptype = LLVMInt32Type ();
421 * llvm_type_to_stack_type:
423 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
426 static G_GNUC_UNUSED LLVMTypeRef
427 llvm_type_to_stack_type (LLVMTypeRef type)
431 if (type == LLVMInt8Type ())
432 return LLVMInt32Type ();
433 else if (type == LLVMInt16Type ())
434 return LLVMInt32Type ();
435 else if (type == LLVMFloatType ())
436 return LLVMDoubleType ();
442 * regtype_to_llvm_type:
444 * Return the LLVM type corresponding to the regtype C used in instruction
448 regtype_to_llvm_type (char c)
452 return LLVMInt32Type ();
454 return LLVMInt64Type ();
456 return LLVMDoubleType ();
465 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
468 op_to_llvm_type (int opcode)
473 return LLVMInt8Type ();
476 return LLVMInt8Type ();
479 return LLVMInt16Type ();
482 return LLVMInt16Type ();
485 return LLVMInt32Type ();
488 return LLVMInt32Type ();
490 return LLVMInt64Type ();
492 return LLVMFloatType ();
494 return LLVMDoubleType ();
496 return LLVMInt64Type ();
498 return LLVMInt32Type ();
500 return LLVMInt64Type ();
503 return LLVMInt8Type ();
506 return LLVMInt16Type ();
509 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
516 return LLVMInt32Type ();
523 return LLVMInt64Type ();
525 printf ("%s\n", mono_inst_name (opcode));
526 g_assert_not_reached ();
532 * load_store_to_llvm_type:
534 * Return the size/sign/zero extension corresponding to the load/store opcode
538 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
544 case OP_LOADI1_MEMBASE:
545 case OP_STOREI1_MEMBASE_REG:
546 case OP_STOREI1_MEMBASE_IMM:
549 return LLVMInt8Type ();
550 case OP_LOADU1_MEMBASE:
554 return LLVMInt8Type ();
555 case OP_LOADI2_MEMBASE:
556 case OP_STOREI2_MEMBASE_REG:
557 case OP_STOREI2_MEMBASE_IMM:
560 return LLVMInt16Type ();
561 case OP_LOADU2_MEMBASE:
565 return LLVMInt16Type ();
566 case OP_LOADI4_MEMBASE:
567 case OP_LOADU4_MEMBASE:
570 case OP_STOREI4_MEMBASE_REG:
571 case OP_STOREI4_MEMBASE_IMM:
573 return LLVMInt32Type ();
574 case OP_LOADI8_MEMBASE:
576 case OP_STOREI8_MEMBASE_REG:
577 case OP_STOREI8_MEMBASE_IMM:
579 return LLVMInt64Type ();
580 case OP_LOADR4_MEMBASE:
581 case OP_STORER4_MEMBASE_REG:
583 return LLVMFloatType ();
584 case OP_LOADR8_MEMBASE:
585 case OP_STORER8_MEMBASE_REG:
587 return LLVMDoubleType ();
588 case OP_LOAD_MEMBASE:
590 case OP_STORE_MEMBASE_REG:
591 case OP_STORE_MEMBASE_IMM:
592 *size = sizeof (gpointer);
593 return IntPtrType ();
595 g_assert_not_reached ();
603 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
606 ovf_op_to_intrins (int opcode)
610 return "llvm.sadd.with.overflow.i32";
612 return "llvm.uadd.with.overflow.i32";
614 return "llvm.ssub.with.overflow.i32";
616 return "llvm.usub.with.overflow.i32";
618 return "llvm.smul.with.overflow.i32";
620 return "llvm.umul.with.overflow.i32";
622 return "llvm.sadd.with.overflow.i64";
624 return "llvm.uadd.with.overflow.i64";
626 return "llvm.ssub.with.overflow.i64";
628 return "llvm.usub.with.overflow.i64";
630 return "llvm.smul.with.overflow.i64";
632 return "llvm.umul.with.overflow.i64";
634 g_assert_not_reached ();
640 simd_op_to_intrins (int opcode)
643 #if defined(TARGET_X86) || defined(TARGET_AMD64)
645 return "llvm.x86.sse2.min.pd";
647 return "llvm.x86.sse.min.ps";
649 return "llvm.x86.sse41.pminud";
651 return "llvm.x86.sse41.pminuw";
653 return "llvm.x86.sse2.pminu.b";
655 return "llvm.x86.sse2.pmins.w";
657 return "llvm.x86.sse2.max.pd";
659 return "llvm.x86.sse.max.ps";
661 return "llvm.x86.sse3.hadd.pd";
663 return "llvm.x86.sse3.hadd.ps";
665 return "llvm.x86.sse3.hsub.pd";
667 return "llvm.x86.sse3.hsub.ps";
669 return "llvm.x86.sse41.pmaxud";
671 return "llvm.x86.sse41.pmaxuw";
673 return "llvm.x86.sse2.pmaxu.b";
675 return "llvm.x86.sse3.addsub.ps";
677 return "llvm.x86.sse3.addsub.pd";
678 case OP_EXTRACT_MASK:
679 return "llvm.x86.sse2.pmovmskb.128";
682 return "llvm.x86.sse2.psrli.w";
685 return "llvm.x86.sse2.psrli.d";
688 return "llvm.x86.sse2.psrli.q";
691 return "llvm.x86.sse2.pslli.w";
694 return "llvm.x86.sse2.pslli.d";
697 return "llvm.x86.sse2.pslli.q";
700 return "llvm.x86.sse2.psrai.w";
703 return "llvm.x86.sse2.psrai.d";
705 return "llvm.x86.sse2.padds.b";
707 return "llvm.x86.sse2.padds.w";
709 return "llvm.x86.sse2.psubs.b";
711 return "llvm.x86.sse2.psubs.w";
712 case OP_PADDB_SAT_UN:
713 return "llvm.x86.sse2.paddus.b";
714 case OP_PADDW_SAT_UN:
715 return "llvm.x86.sse2.paddus.w";
716 case OP_PSUBB_SAT_UN:
717 return "llvm.x86.sse2.psubus.b";
718 case OP_PSUBW_SAT_UN:
719 return "llvm.x86.sse2.psubus.w";
721 return "llvm.x86.sse2.pavg.b";
723 return "llvm.x86.sse2.pavg.w";
725 return "llvm.x86.sse.sqrt.ps";
727 return "llvm.x86.sse2.sqrt.pd";
729 return "llvm.x86.sse.rsqrt.ps";
731 return "llvm.x86.sse.rcp.ps";
733 return "llvm.x86.sse2.pcmpeq.b";
735 return "llvm.x86.sse2.pcmpeq.w";
737 return "llvm.x86.sse2.pcmpeq.d";
739 return "llvm.x86.sse41.pcmpeqq";
741 return "llvm.x86.sse2.pcmpgt.b";
743 return "llvm.x86.sse2.cvtdq2pd";
745 return "llvm.x86.sse2.cvtdq2ps";
747 return "llvm.x86.sse2.cvtpd2dq";
749 return "llvm.x86.sse2.cvtps2dq";
751 return "llvm.x86.sse2.cvtpd2ps";
753 return "llvm.x86.sse2.cvtps2pd";
755 return "llvm.x86.sse2.cvttpd2dq";
757 return "llvm.x86.sse2.cvttps2dq";
759 return "llvm.x86.sse.cmp.ps";
761 return "llvm.x86.sse2.cmp.pd";
763 return "llvm.x86.sse2.packsswb.128";
765 return "llvm.x86.sse2.packssdw.128";
767 return "llvm.x86.sse2.packuswb.128";
769 return "llvm.x86.sse41.packusdw";
771 return "llvm.x86.sse2.pmulh.w";
772 case OP_PMULW_HIGH_UN:
773 return "llvm.x86.sse2.pmulhu.w";
776 g_assert_not_reached ();
782 simd_op_to_llvm_type (int opcode)
784 #if defined(TARGET_X86) || defined(TARGET_AMD64)
788 return type_to_simd_type (MONO_TYPE_R8);
791 return type_to_simd_type (MONO_TYPE_I8);
794 return type_to_simd_type (MONO_TYPE_I4);
799 return type_to_simd_type (MONO_TYPE_I2);
803 return type_to_simd_type (MONO_TYPE_I1);
805 return type_to_simd_type (MONO_TYPE_R4);
808 return type_to_simd_type (MONO_TYPE_I4);
812 return type_to_simd_type (MONO_TYPE_R8);
816 return type_to_simd_type (MONO_TYPE_R4);
817 case OP_EXTRACT_MASK:
818 return type_to_simd_type (MONO_TYPE_I1);
824 return type_to_simd_type (MONO_TYPE_R4);
827 return type_to_simd_type (MONO_TYPE_R8);
829 g_assert_not_reached ();
840 * Return the LLVM basic block corresponding to BB.
842 static LLVMBasicBlockRef
843 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
847 if (ctx->bblocks [bb->block_num].bblock == NULL) {
848 if (bb->flags & BB_EXCEPTION_HANDLER) {
849 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
850 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
852 sprintf (bb_name, "BB%d", bb->block_num);
855 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
856 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
859 return ctx->bblocks [bb->block_num].bblock;
865 * Return the last LLVM bblock corresponding to BB.
866 * This might not be equal to the bb returned by get_bb () since we need to generate
867 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
869 static LLVMBasicBlockRef
870 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
873 return ctx->bblocks [bb->block_num].end_bblock;
876 static LLVMBasicBlockRef
877 gen_bb (EmitContext *ctx, const char *prefix)
881 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
882 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
888 * Return the target of the patch identified by TYPE and TARGET.
891 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
895 memset (&ji, 0, sizeof (ji));
897 ji.data.target = target;
899 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
905 * Emit code to convert the LLVM value V to DTYPE.
908 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
910 LLVMTypeRef stype = LLVMTypeOf (v);
912 if (stype != dtype) {
913 gboolean ext = FALSE;
916 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
918 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
920 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
924 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
926 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
927 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
930 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
931 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
932 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
933 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
934 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
935 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
936 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
937 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
939 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
940 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
941 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
942 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
943 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
944 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
946 #ifdef MONO_ARCH_SOFT_FLOAT
947 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
948 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
949 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
950 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
953 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
954 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
957 LLVMDumpValue (LLVMConstNull (dtype));
958 g_assert_not_reached ();
966 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
968 return convert_full (ctx, v, dtype, FALSE);
972 * emit_volatile_load:
974 * If vreg is volatile, emit a load from its address.
977 emit_volatile_load (EmitContext *ctx, int vreg)
981 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
982 t = ctx->vreg_cli_types [vreg];
983 if (t && !t->byref) {
985 * Might have to zero extend since llvm doesn't have
988 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
989 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
990 else if (t->type == MONO_TYPE_U8)
991 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
998 * emit_volatile_store:
1000 * If VREG is volatile, emit a store from its value to its address.
1003 emit_volatile_store (EmitContext *ctx, int vreg)
1005 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1007 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1008 g_assert (ctx->addresses [vreg]);
1009 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1015 * Maps parameter indexes in the original signature to parameter indexes
1016 * in the LLVM signature.
1019 /* The indexes of various special arguments in the LLVM signature */
1020 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1024 * sig_to_llvm_sig_full:
1026 * Return the LLVM signature corresponding to the mono signature SIG using the
1027 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1030 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1033 LLVMTypeRef ret_type;
1034 LLVMTypeRef *param_types = NULL;
1036 int i, j, pindex, vret_arg_pindex = 0;
1038 gboolean vretaddr = FALSE;
1041 memset (sinfo, 0, sizeof (LLVMSigInfo));
1043 ret_type = type_to_llvm_type (ctx, sig->ret);
1044 CHECK_FAILURE (ctx);
1046 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1047 /* LLVM models this by returning an aggregate value */
1048 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1049 LLVMTypeRef members [2];
1051 members [0] = IntPtrType ();
1052 ret_type = LLVMStructType (members, 1, FALSE);
1054 g_assert_not_reached ();
1056 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1057 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1059 ret_type = LLVMVoidType ();
1062 pindexes = g_new0 (int, sig->param_count);
1063 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1065 if (cinfo && cinfo->rgctx_arg) {
1067 sinfo->rgctx_arg_pindex = pindex;
1068 param_types [pindex] = IntPtrType ();
1071 if (cinfo && cinfo->imt_arg) {
1073 sinfo->imt_arg_pindex = pindex;
1074 param_types [pindex] = IntPtrType ();
1078 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1079 vret_arg_pindex = pindex;
1080 if (cinfo->vret_arg_index == 1) {
1081 /* Add the slots consumed by the first argument */
1082 LLVMArgInfo *ainfo = &cinfo->args [0];
1083 switch (ainfo->storage) {
1084 case LLVMArgVtypeInReg:
1085 for (j = 0; j < 2; ++j) {
1086 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1096 sinfo->vret_arg_pindex = vret_arg_pindex;
1099 if (vretaddr && vret_arg_pindex == pindex)
1100 param_types [pindex ++] = IntPtrType ();
1103 sinfo->this_arg_pindex = pindex;
1104 param_types [pindex ++] = IntPtrType ();
1106 if (vretaddr && vret_arg_pindex == pindex)
1107 param_types [pindex ++] = IntPtrType ();
1108 for (i = 0; i < sig->param_count; ++i) {
1109 if (vretaddr && vret_arg_pindex == pindex)
1110 param_types [pindex ++] = IntPtrType ();
1111 pindexes [i] = pindex;
1112 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1113 for (j = 0; j < 2; ++j) {
1114 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1116 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1121 g_assert_not_reached ();
1124 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1125 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1126 CHECK_FAILURE (ctx);
1127 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1130 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1133 if (vretaddr && vret_arg_pindex == pindex)
1134 param_types [pindex ++] = IntPtrType ();
1136 CHECK_FAILURE (ctx);
1138 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1139 g_free (param_types);
1142 sinfo->pindexes = pindexes;
1150 g_free (param_types);
1156 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1158 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1162 * LLVMFunctionType1:
1164 * Create an LLVM function type from the arguments.
1166 static G_GNUC_UNUSED LLVMTypeRef
1167 LLVMFunctionType1(LLVMTypeRef ReturnType,
1168 LLVMTypeRef ParamType1,
1171 LLVMTypeRef param_types [1];
1173 param_types [0] = ParamType1;
1175 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1179 * LLVMFunctionType2:
1181 * Create an LLVM function type from the arguments.
1183 static G_GNUC_UNUSED LLVMTypeRef
1184 LLVMFunctionType2(LLVMTypeRef ReturnType,
1185 LLVMTypeRef ParamType1,
1186 LLVMTypeRef ParamType2,
1189 LLVMTypeRef param_types [2];
1191 param_types [0] = ParamType1;
1192 param_types [1] = ParamType2;
1194 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1198 * LLVMFunctionType3:
1200 * Create an LLVM function type from the arguments.
1202 static G_GNUC_UNUSED LLVMTypeRef
1203 LLVMFunctionType3(LLVMTypeRef ReturnType,
1204 LLVMTypeRef ParamType1,
1205 LLVMTypeRef ParamType2,
1206 LLVMTypeRef ParamType3,
1209 LLVMTypeRef param_types [3];
1211 param_types [0] = ParamType1;
1212 param_types [1] = ParamType2;
1213 param_types [2] = ParamType3;
1215 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1221 * Create an LLVM builder and remember it so it can be freed later.
1223 static LLVMBuilderRef
1224 create_builder (EmitContext *ctx)
1226 LLVMBuilderRef builder = LLVMCreateBuilder ();
1228 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1234 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1236 char *callee_name = mono_aot_get_plt_symbol (type, data);
1237 LLVMValueRef callee;
1242 if (ctx->cfg->compile_aot)
1243 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1244 mono_add_patch_info (ctx->cfg, 0, type, data);
1247 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1249 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1251 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1253 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1260 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1262 MonoMethodHeader *header = cfg->header;
1263 MonoExceptionClause *clause;
1267 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1268 return (bb->region >> 8) - 1;
1271 for (i = 0; i < header->num_clauses; ++i) {
1272 clause = &header->clauses [i];
1274 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1282 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1284 LLVMValueRef md_arg;
1287 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1288 md_arg = LLVMMDString ("mono", 4);
1289 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1295 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1299 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1301 MonoCompile *cfg = ctx->cfg;
1303 LLVMBuilderRef builder = *builder_ref;
1306 clause_index = get_handler_clause (cfg, bb);
1308 if (clause_index != -1) {
1309 MonoMethodHeader *header = cfg->header;
1310 MonoExceptionClause *ec = &header->clauses [clause_index];
1311 MonoBasicBlock *tblock;
1312 LLVMBasicBlockRef ex_bb, noex_bb;
1315 * Have to use an invoke instead of a call, branching to the
1316 * handler bblock of the clause containing this bblock.
1319 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1321 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1324 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1326 ex_bb = get_bb (ctx, tblock);
1328 noex_bb = gen_bb (ctx, "NOEX_BB");
1331 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1333 builder = ctx->builder = create_builder (ctx);
1334 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1336 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1338 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1339 ctx->builder = builder;
1342 *builder_ref = ctx->builder;
1348 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1350 const char *intrins_name;
1351 LLVMValueRef args [16], res;
1352 LLVMTypeRef addr_type;
1354 if (is_faulting && bb->region != -1) {
1356 * We handle loads which can fault by calling a mono specific intrinsic
1357 * using an invoke, so they are handled properly inside try blocks.
1358 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1359 * are marked with IntrReadArgMem.
1363 intrins_name = "llvm.mono.load.i8.p0i8";
1366 intrins_name = "llvm.mono.load.i16.p0i16";
1369 intrins_name = "llvm.mono.load.i32.p0i32";
1372 intrins_name = "llvm.mono.load.i64.p0i64";
1375 g_assert_not_reached ();
1378 addr_type = LLVMTypeOf (addr);
1379 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1380 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1383 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1384 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1385 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1387 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1388 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1389 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1390 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1397 * We emit volatile loads for loads which can fault, because otherwise
1398 * LLVM will generate invalid code when encountering a load from a
1401 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1403 /* Mark it with a custom metadata */
1406 set_metadata_flag (res, "mono.faulting.load");
1414 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1416 const char *intrins_name;
1417 LLVMValueRef args [16];
1419 if (is_faulting && bb->region != -1) {
1422 intrins_name = "llvm.mono.store.i8.p0i8";
1425 intrins_name = "llvm.mono.store.i16.p0i16";
1428 intrins_name = "llvm.mono.store.i32.p0i32";
1431 intrins_name = "llvm.mono.store.i64.p0i64";
1434 g_assert_not_reached ();
1437 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1438 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1439 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1444 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1445 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1446 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1448 LLVMBuildStore (*builder_ref, value, addr);
1453 * emit_cond_system_exception:
1455 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1456 * Might set the ctx exception.
1459 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1461 LLVMBasicBlockRef ex_bb, noex_bb;
1462 LLVMBuilderRef builder;
1463 MonoClass *exc_class;
1464 LLVMValueRef args [2];
1466 ex_bb = gen_bb (ctx, "EX_BB");
1467 noex_bb = gen_bb (ctx, "NOEX_BB");
1469 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1471 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1472 g_assert (exc_class);
1474 /* Emit exception throwing code */
1475 builder = create_builder (ctx);
1476 LLVMPositionBuilderAtEnd (builder, ex_bb);
1478 if (!ctx->lmodule->throw_corlib_exception) {
1479 LLVMValueRef callee;
1481 const char *icall_name;
1483 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1484 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1485 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1486 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1487 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1488 sig = sig_to_llvm_sig (ctx, throw_sig);
1490 if (ctx->cfg->compile_aot) {
1491 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1493 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1496 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1497 * - On x86, LLVM generated code doesn't push the arguments
1498 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1499 * arguments, not a pc offset.
1501 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1504 mono_memory_barrier ();
1505 ctx->lmodule->throw_corlib_exception = callee;
1509 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1511 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1514 * The LLVM mono branch contains changes so a block address can be passed as an
1515 * argument to a call.
1517 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1518 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1520 LLVMBuildUnreachable (builder);
1522 ctx->builder = create_builder (ctx);
1523 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1525 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1532 * emit_reg_to_vtype:
1534 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1537 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1541 size = get_vtype_size (t);
1543 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1544 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1547 for (j = 0; j < 2; ++j) {
1548 LLVMValueRef index [2], addr;
1549 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1550 LLVMTypeRef part_type;
1552 if (ainfo->pair_storage [j] == LLVMArgNone)
1555 part_type = LLVMIntType (part_size * 8);
1556 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1557 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1558 addr = LLVMBuildGEP (builder, address, index, 1, "");
1560 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1561 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1562 addr = LLVMBuildGEP (builder, address, index, 2, "");
1564 switch (ainfo->pair_storage [j]) {
1566 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1571 g_assert_not_reached ();
1574 size -= sizeof (gpointer);
1579 * emit_vtype_to_reg:
1581 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1582 * into REGS, and the number of registers into NREGS.
1585 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1590 size = get_vtype_size (t);
1592 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1593 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1596 for (j = 0; j < 2; ++j) {
1597 LLVMValueRef index [2], addr;
1598 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1600 if (ainfo->pair_storage [j] == LLVMArgNone)
1603 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1604 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1605 addr = LLVMBuildGEP (builder, address, index, 1, "");
1607 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1608 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1609 addr = LLVMBuildGEP (builder, address, index, 2, "");
1611 switch (ainfo->pair_storage [j]) {
1613 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1618 g_assert_not_reached ();
1620 size -= sizeof (gpointer);
1627 build_alloca (EmitContext *ctx, MonoType *t)
1629 MonoClass *k = mono_class_from_mono_type (t);
1632 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1635 align = mono_class_min_align (k);
1637 /* Sometimes align is not a power of 2 */
1638 while (mono_is_power_of_two (align) == -1)
1642 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1643 * get executed every time control reaches them.
1645 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1647 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1648 return ctx->last_alloca;
1652 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1655 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1657 LLVMTypeRef used_type;
1658 LLVMValueRef used, used_elem;
1660 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1661 used = LLVMAddGlobal (module, used_type, "llvm.used");
1662 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1663 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1664 LLVMSetLinkage (used, LLVMAppendingLinkage);
1665 LLVMSetSection (used, "llvm.metadata");
1671 * Emit code to load/convert arguments.
1674 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1677 MonoCompile *cfg = ctx->cfg;
1678 MonoMethodSignature *sig = ctx->sig;
1679 LLVMCallInfo *linfo = ctx->linfo;
1682 ctx->alloca_builder = create_builder (ctx);
1685 * Handle indirect/volatile variables by allocating memory for them
1686 * using 'alloca', and storing their address in a temporary.
1688 for (i = 0; i < cfg->num_varinfo; ++i) {
1689 MonoInst *var = cfg->varinfo [i];
1692 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1693 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1694 CHECK_FAILURE (ctx);
1695 /* Could be already created by an OP_VPHI */
1696 if (!ctx->addresses [var->dreg])
1697 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1698 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1702 for (i = 0; i < sig->param_count; ++i) {
1703 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1704 int reg = cfg->args [i + sig->hasthis]->dreg;
1706 if (ainfo->storage == LLVMArgVtypeInReg) {
1707 LLVMValueRef regs [2];
1710 * Emit code to save the argument from the registers to
1711 * the real argument.
1713 pindex = ctx->pindexes [i];
1714 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1715 if (ainfo->pair_storage [1] != LLVMArgNone)
1716 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1720 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1722 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1724 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1725 /* Treat these as normal values */
1726 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1728 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1729 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1731 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1732 /* Treat these as normal values */
1733 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1736 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1741 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1743 emit_volatile_store (ctx, cfg->args [0]->dreg);
1744 for (i = 0; i < sig->param_count; ++i)
1745 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1746 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1748 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1749 LLVMValueRef this_alloc;
1752 * The exception handling code needs the location where the this argument was
1753 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1754 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1755 * location into the LSDA.
1757 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1758 /* This volatile store will keep the alloca alive */
1759 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1761 set_metadata_flag (this_alloc, "mono.this");
1764 if (cfg->rgctx_var) {
1765 LLVMValueRef rgctx_alloc, store;
1768 * We handle the rgctx arg similarly to the this pointer.
1770 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1771 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1772 /* This volatile store will keep the alloca alive */
1773 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1775 set_metadata_flag (rgctx_alloc, "mono.this");
1779 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1780 * it needs to continue normally, or return back to the exception handling system.
1782 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1783 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1784 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1785 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1789 sprintf (name, "finally_ind_bb%d", bb->block_num);
1790 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1791 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1793 ctx->bblocks [bb->block_num].finally_ind = val;
1796 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1797 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1798 * LLVM optimizer passes.
1800 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1801 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1809 /* Have to export this for AOT */
1811 mono_personality (void);
1814 mono_personality (void)
1817 g_assert_not_reached ();
1821 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1823 MonoCompile *cfg = ctx->cfg;
1824 LLVMModuleRef module = ctx->module;
1825 LLVMValueRef *values = ctx->values;
1826 LLVMValueRef *addresses = ctx->addresses;
1827 MonoCallInst *call = (MonoCallInst*)ins;
1828 MonoMethodSignature *sig = call->signature;
1829 LLVMValueRef callee = NULL, lcall;
1831 LLVMCallInfo *cinfo;
1835 LLVMTypeRef llvm_sig;
1837 gboolean virtual, calli;
1838 LLVMBuilderRef builder = *builder_ref;
1841 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1842 LLVM_FAILURE (ctx, "non-default callconv");
1844 cinfo = call->cinfo;
1845 if (call->rgctx_arg_reg)
1846 cinfo->rgctx_arg = TRUE;
1847 if (call->imt_arg_reg)
1848 cinfo->imt_arg = TRUE;
1850 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1852 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1853 CHECK_FAILURE (ctx);
1855 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);
1856 calli = (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);
1858 /* FIXME: Avoid creating duplicate methods */
1860 if (ins->flags & MONO_INST_HAS_METHOD) {
1864 if (cfg->compile_aot) {
1865 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1867 LLVM_FAILURE (ctx, "can't encode patch");
1869 callee = LLVMAddFunction (module, "", llvm_sig);
1872 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1874 LLVMAddGlobalMapping (ee, callee, target);
1879 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1885 memset (&ji, 0, sizeof (ji));
1886 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1887 ji.data.target = info->name;
1889 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1891 if (cfg->compile_aot) {
1892 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1894 LLVM_FAILURE (ctx, "can't encode patch");
1896 callee = LLVMAddFunction (module, "", llvm_sig);
1897 target = (gpointer)mono_icall_get_wrapper (info);
1898 LLVMAddGlobalMapping (ee, callee, target);
1901 if (cfg->compile_aot) {
1903 if (cfg->abs_patches) {
1904 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1906 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1908 LLVM_FAILURE (ctx, "can't encode patch");
1912 LLVM_FAILURE (ctx, "aot");
1914 callee = LLVMAddFunction (module, "", llvm_sig);
1916 if (cfg->abs_patches) {
1917 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1920 * FIXME: Some trampolines might have
1921 * their own calling convention on some platforms.
1923 #ifndef TARGET_AMD64
1924 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
1925 LLVM_FAILURE (ctx, "trampoline with own cconv");
1927 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1928 LLVMAddGlobalMapping (ee, callee, target);
1932 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1938 int size = sizeof (gpointer);
1941 g_assert (ins->inst_offset % size == 0);
1942 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1944 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1946 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1948 if (ins->flags & MONO_INST_HAS_METHOD) {
1953 * Collect and convert arguments
1955 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
1956 args = alloca (len);
1957 memset (args, 0, len);
1958 l = call->out_ireg_args;
1960 if (call->rgctx_arg_reg) {
1961 g_assert (values [call->rgctx_arg_reg]);
1962 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1964 if (call->imt_arg_reg) {
1965 g_assert (values [call->imt_arg_reg]);
1966 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1970 if (!addresses [call->inst.dreg])
1971 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1972 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1975 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1978 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1982 pindex = sinfo.this_arg_pindex;
1984 pindex = sinfo.pindexes [i - 1];
1986 pindex = sinfo.pindexes [i];
1989 regpair = (guint32)(gssize)(l->data);
1990 reg = regpair & 0xffffff;
1991 args [pindex] = values [reg];
1992 if (ainfo->storage == LLVMArgVtypeInReg) {
1994 LLVMValueRef regs [2];
1999 g_assert (addresses [reg]);
2001 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2002 for (j = 0; j < nregs; ++j)
2003 args [pindex ++] = regs [j];
2006 // FIXME: Get rid of the VMOVE
2007 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2008 g_assert (addresses [reg]);
2009 args [pindex] = addresses [reg];
2011 g_assert (args [pindex]);
2012 if (i == 0 && sig->hasthis)
2013 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2015 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2021 // FIXME: Align call sites
2027 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2029 #ifdef LLVM_MONO_BRANCH
2031 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2033 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2034 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2036 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2037 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2039 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2041 if (call->rgctx_arg_reg)
2042 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2043 if (call->imt_arg_reg)
2044 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2047 /* Add byval attributes if needed */
2048 for (i = 0; i < sig->param_count; ++i) {
2049 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2051 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2052 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2057 * Convert the result
2059 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2060 LLVMValueRef regs [2];
2062 if (!addresses [ins->dreg])
2063 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2065 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2066 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2067 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2069 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2070 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2071 /* If the method returns an unsigned value, need to zext it */
2073 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2076 *builder_ref = ctx->builder;
2078 g_free (sinfo.pindexes);
2086 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2088 MonoCompile *cfg = ctx->cfg;
2089 MonoMethodSignature *sig = ctx->sig;
2090 LLVMValueRef method = ctx->lmethod;
2091 LLVMValueRef *values = ctx->values;
2092 LLVMValueRef *addresses = ctx->addresses;
2094 LLVMCallInfo *linfo = ctx->linfo;
2095 LLVMModuleRef module = ctx->module;
2096 BBInfo *bblocks = ctx->bblocks;
2098 LLVMBasicBlockRef cbb;
2099 LLVMBuilderRef builder, starting_builder;
2100 gboolean has_terminator;
2102 LLVMValueRef lhs, rhs;
2105 cbb = get_bb (ctx, bb);
2106 builder = create_builder (ctx);
2107 ctx->builder = builder;
2108 LLVMPositionBuilderAtEnd (builder, cbb);
2110 if (bb == cfg->bb_entry)
2111 emit_entry_bb (ctx, builder);
2112 CHECK_FAILURE (ctx);
2114 if (bb->flags & BB_EXCEPTION_HANDLER) {
2116 LLVMValueRef personality;
2117 LLVMBasicBlockRef target_bb;
2119 static gint32 mapping_inited;
2120 static int ti_generator;
2123 LLVMValueRef type_info;
2126 if (!bblocks [bb->block_num].invoke_target) {
2128 * LLVM asserts if llvm.eh.selector is called from a bblock which
2129 * doesn't have an invoke pointing at it.
2130 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2132 LLVM_FAILURE (ctx, "handler without invokes");
2135 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2137 if (cfg->compile_aot) {
2138 /* Use a dummy personality function */
2139 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2140 g_assert (personality);
2142 personality = LLVMGetNamedFunction (module, "mono_personality");
2143 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2144 LLVMAddGlobalMapping (ee, personality, mono_personality);
2147 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2149 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2152 * Create the type info
2154 sprintf (ti_name, "type_info_%d", ti_generator);
2157 if (cfg->compile_aot) {
2158 /* decode_eh_frame () in aot-runtime.c will decode this */
2159 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2160 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2162 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2163 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2166 * Enabling this causes llc to crash:
2167 * http://llvm.org/bugs/show_bug.cgi?id=6102
2169 //LLVM_FAILURE (ctx, "aot+clauses");
2172 * After the cfg mempool is freed, the type info will point to stale memory,
2173 * but this is not a problem, since we decode it once in exception_cb during
2176 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2177 *(gint32*)ti = clause_index;
2179 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2181 LLVMAddGlobalMapping (ee, type_info, ti);
2185 LLVMTypeRef members [2], ret_type;
2186 LLVMValueRef landing_pad;
2188 members [0] = i8ptr;
2189 members [1] = LLVMInt32Type ();
2190 ret_type = LLVMStructType (members, 2, FALSE);
2192 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2193 LLVMAddClause (landing_pad, type_info);
2195 /* Store the exception into the exvar */
2196 if (bb->in_scount == 1) {
2197 g_assert (bb->in_scount == 1);
2198 exvar = bb->in_stack [0];
2200 // FIXME: This is shared with filter clauses ?
2201 g_assert (!values [exvar->dreg]);
2203 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2204 emit_volatile_store (ctx, exvar->dreg);
2208 /* Start a new bblock which CALL_HANDLER can branch to */
2209 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2211 LLVMBuildBr (builder, target_bb);
2213 ctx->builder = builder = create_builder (ctx);
2214 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2216 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2220 has_terminator = FALSE;
2221 starting_builder = builder;
2222 for (ins = bb->code; ins; ins = ins->next) {
2223 const char *spec = LLVM_INS_INFO (ins->opcode);
2225 char dname_buf [128];
2228 if (nins > 5000 && builder == starting_builder) {
2229 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2230 LLVM_FAILURE (ctx, "basic block too long");
2234 /* There could be instructions after a terminator, skip them */
2237 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2238 sprintf (dname_buf, "t%d", ins->dreg);
2242 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2243 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2245 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2246 lhs = emit_volatile_load (ctx, ins->sreg1);
2248 /* It is ok for SETRET to have an uninitialized argument */
2249 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2250 LLVM_FAILURE (ctx, "sreg1");
2251 lhs = values [ins->sreg1];
2257 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2258 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2259 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2260 rhs = emit_volatile_load (ctx, ins->sreg2);
2262 if (!values [ins->sreg2])
2263 LLVM_FAILURE (ctx, "sreg2");
2264 rhs = values [ins->sreg2];
2270 //mono_print_ins (ins);
2271 switch (ins->opcode) {
2274 case OP_LIVERANGE_START:
2275 case OP_LIVERANGE_END:
2278 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2281 #if SIZEOF_VOID_P == 4
2282 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2284 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2288 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2291 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2294 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2295 has_terminator = TRUE;
2301 LLVMBasicBlockRef new_bb;
2302 LLVMBuilderRef new_builder;
2304 // The default branch is already handled
2305 // FIXME: Handle it here
2307 /* Start new bblock */
2308 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2309 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2311 lhs = convert (ctx, lhs, LLVMInt32Type ());
2312 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2313 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2314 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2316 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2319 new_builder = create_builder (ctx);
2320 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2321 LLVMBuildUnreachable (new_builder);
2323 has_terminator = TRUE;
2324 g_assert (!ins->next);
2330 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2331 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2332 LLVMValueRef part1, retval;
2335 size = get_vtype_size (sig->ret);
2337 g_assert (addresses [ins->sreg1]);
2339 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2340 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2342 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2344 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2346 LLVMBuildRet (builder, retval);
2350 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2351 LLVMBuildRetVoid (builder);
2355 if (!lhs || ctx->is_dead [ins->sreg1]) {
2357 * The method did not set its return value, probably because it
2358 * ends with a throw.
2361 LLVMBuildRetVoid (builder);
2363 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2365 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2367 has_terminator = TRUE;
2373 case OP_ICOMPARE_IMM:
2374 case OP_LCOMPARE_IMM:
2375 case OP_COMPARE_IMM: {
2379 if (ins->next->opcode == OP_NOP)
2382 if (ins->next->opcode == OP_BR)
2383 /* The comparison result is not needed */
2386 rel = mono_opcode_to_cond (ins->next->opcode);
2388 if (ins->opcode == OP_ICOMPARE_IMM) {
2389 lhs = convert (ctx, lhs, LLVMInt32Type ());
2390 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2392 if (ins->opcode == OP_LCOMPARE_IMM) {
2393 lhs = convert (ctx, lhs, LLVMInt64Type ());
2394 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2396 if (ins->opcode == OP_LCOMPARE) {
2397 lhs = convert (ctx, lhs, LLVMInt64Type ());
2398 rhs = convert (ctx, rhs, LLVMInt64Type ());
2400 if (ins->opcode == OP_ICOMPARE) {
2401 lhs = convert (ctx, lhs, LLVMInt32Type ());
2402 rhs = convert (ctx, rhs, LLVMInt32Type ());
2406 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2407 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2408 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2409 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2412 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2413 if (ins->opcode == OP_FCOMPARE)
2414 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2415 else if (ins->opcode == OP_COMPARE_IMM)
2416 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2417 else if (ins->opcode == OP_LCOMPARE_IMM) {
2418 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2419 /* The immediate is encoded in two fields */
2420 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2421 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2423 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2426 else if (ins->opcode == OP_COMPARE)
2427 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2429 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2431 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2432 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2434 * If the target bb contains PHI instructions, LLVM requires
2435 * two PHI entries for this bblock, while we only generate one.
2436 * So convert this to an unconditional bblock. (bxc #171).
2438 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2440 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2442 has_terminator = TRUE;
2443 } else if (MONO_IS_SETCC (ins->next)) {
2444 sprintf (dname_buf, "t%d", ins->next->dreg);
2446 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2448 /* Add stores for volatile variables */
2449 emit_volatile_store (ctx, ins->next->dreg);
2450 } else if (MONO_IS_COND_EXC (ins->next)) {
2451 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2452 CHECK_FAILURE (ctx);
2453 builder = ctx->builder;
2455 LLVM_FAILURE (ctx, "next");
2469 rel = mono_opcode_to_cond (ins->opcode);
2471 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2472 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2480 gboolean empty = TRUE;
2482 /* Check that all input bblocks really branch to us */
2483 for (i = 0; i < bb->in_count; ++i) {
2484 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2485 ins->inst_phi_args [i + 1] = -1;
2491 /* LLVM doesn't like phi instructions with zero operands */
2492 ctx->is_dead [ins->dreg] = TRUE;
2496 /* Created earlier, insert it now */
2497 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2499 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2500 int sreg1 = ins->inst_phi_args [i + 1];
2504 * Count the number of times the incoming bblock branches to us,
2505 * since llvm requires a separate entry for each.
2507 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2508 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2511 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2512 if (switch_ins->inst_many_bb [j] == bb)
2519 /* Remember for later */
2520 for (j = 0; j < count; ++j) {
2521 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2524 node->in_bb = bb->in_bb [i];
2526 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);
2536 values [ins->dreg] = lhs;
2539 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2542 values [ins->dreg] = lhs;
2544 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2546 * This is added by the spilling pass in case of the JIT,
2547 * but we have to do it ourselves.
2549 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2583 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2584 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2586 switch (ins->opcode) {
2589 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2593 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2597 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2601 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2605 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2609 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2613 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2616 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2620 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2624 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2628 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2632 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2636 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2640 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2644 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2647 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2650 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2654 g_assert_not_reached ();
2661 case OP_IREM_UN_IMM:
2663 case OP_IDIV_UN_IMM:
2669 case OP_ISHR_UN_IMM:
2678 case OP_LSHR_UN_IMM:
2686 if (spec [MONO_INST_SRC1] == 'l') {
2687 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2689 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2692 #if SIZEOF_VOID_P == 4
2693 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2694 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2697 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2698 lhs = convert (ctx, lhs, IntPtrType ());
2699 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2700 switch (ins->opcode) {
2704 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2708 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2712 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2716 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2718 case OP_IDIV_UN_IMM:
2719 case OP_LDIV_UN_IMM:
2720 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2724 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2726 case OP_IREM_UN_IMM:
2727 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2732 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2736 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2740 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2745 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2750 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2752 case OP_ISHR_UN_IMM:
2753 /* This is used to implement conv.u4, so the lhs could be an i8 */
2754 lhs = convert (ctx, lhs, LLVMInt32Type ());
2755 imm = convert (ctx, imm, LLVMInt32Type ());
2756 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2758 case OP_LSHR_UN_IMM:
2759 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2762 g_assert_not_reached ();
2767 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2770 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2773 lhs = convert (ctx, lhs, LLVMDoubleType ());
2774 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2777 guint32 v = 0xffffffff;
2778 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2782 guint64 v = 0xffffffffffffffffLL;
2783 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2786 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2788 LLVMValueRef v1, v2;
2790 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2791 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2792 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2797 case OP_ICONV_TO_I1:
2798 case OP_ICONV_TO_I2:
2799 case OP_ICONV_TO_I4:
2800 case OP_ICONV_TO_U1:
2801 case OP_ICONV_TO_U2:
2802 case OP_ICONV_TO_U4:
2803 case OP_LCONV_TO_I1:
2804 case OP_LCONV_TO_I2:
2805 case OP_LCONV_TO_U1:
2806 case OP_LCONV_TO_U2:
2807 case OP_LCONV_TO_U4: {
2810 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);
2812 /* Have to do two casts since our vregs have type int */
2813 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2815 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2817 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2820 case OP_ICONV_TO_I8:
2821 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2823 case OP_ICONV_TO_U8:
2824 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2826 case OP_FCONV_TO_I4:
2827 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2829 case OP_FCONV_TO_I1:
2830 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2832 case OP_FCONV_TO_U1:
2833 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2835 case OP_FCONV_TO_I2:
2836 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2838 case OP_FCONV_TO_U2:
2839 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2841 case OP_FCONV_TO_I8:
2842 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2845 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2847 case OP_ICONV_TO_R8:
2848 case OP_LCONV_TO_R8:
2849 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2851 case OP_LCONV_TO_R_UN:
2852 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2854 #if SIZEOF_VOID_P == 4
2857 case OP_LCONV_TO_I4:
2858 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2860 case OP_ICONV_TO_R4:
2861 case OP_LCONV_TO_R4:
2862 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2863 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2865 case OP_FCONV_TO_R4:
2866 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2867 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2870 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2873 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2876 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2878 case OP_LOCALLOC_IMM: {
2881 guint32 size = ins->inst_imm;
2882 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2884 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2886 if (ins->flags & MONO_INST_INIT) {
2887 LLVMValueRef args [5];
2890 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2891 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2892 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2893 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2894 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2897 values [ins->dreg] = v;
2901 LLVMValueRef v, size;
2903 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), "");
2905 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2907 if (ins->flags & MONO_INST_INIT) {
2908 LLVMValueRef args [5];
2911 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2913 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2914 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2915 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2917 values [ins->dreg] = v;
2921 case OP_LOADI1_MEMBASE:
2922 case OP_LOADU1_MEMBASE:
2923 case OP_LOADI2_MEMBASE:
2924 case OP_LOADU2_MEMBASE:
2925 case OP_LOADI4_MEMBASE:
2926 case OP_LOADU4_MEMBASE:
2927 case OP_LOADI8_MEMBASE:
2928 case OP_LOADR4_MEMBASE:
2929 case OP_LOADR8_MEMBASE:
2930 case OP_LOAD_MEMBASE:
2938 LLVMValueRef base, index, addr;
2940 gboolean sext = FALSE, zext = FALSE;
2941 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2943 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2948 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)) {
2949 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2954 if (ins->inst_offset == 0) {
2956 } else if (ins->inst_offset % size != 0) {
2957 /* Unaligned load */
2958 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2959 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2961 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2962 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2966 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2968 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2970 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2972 * These will signal LLVM that these loads do not alias any stores, and
2973 * they can't fail, allowing them to be hoisted out of loops.
2975 set_metadata_flag (values [ins->dreg], "mono.noalias");
2976 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2980 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2982 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2983 else if (ins->opcode == OP_LOADR4_MEMBASE)
2984 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2988 case OP_STOREI1_MEMBASE_REG:
2989 case OP_STOREI2_MEMBASE_REG:
2990 case OP_STOREI4_MEMBASE_REG:
2991 case OP_STOREI8_MEMBASE_REG:
2992 case OP_STORER4_MEMBASE_REG:
2993 case OP_STORER8_MEMBASE_REG:
2994 case OP_STORE_MEMBASE_REG: {
2996 LLVMValueRef index, addr;
2998 gboolean sext = FALSE, zext = FALSE;
2999 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3001 if (!values [ins->inst_destbasereg])
3002 LLVM_FAILURE (ctx, "inst_destbasereg");
3004 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3006 if (ins->inst_offset % size != 0) {
3007 /* Unaligned store */
3008 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3009 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3011 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3012 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3014 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3018 case OP_STOREI1_MEMBASE_IMM:
3019 case OP_STOREI2_MEMBASE_IMM:
3020 case OP_STOREI4_MEMBASE_IMM:
3021 case OP_STOREI8_MEMBASE_IMM:
3022 case OP_STORE_MEMBASE_IMM: {
3024 LLVMValueRef index, addr;
3026 gboolean sext = FALSE, zext = FALSE;
3027 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3029 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3031 if (ins->inst_offset % size != 0) {
3032 /* Unaligned store */
3033 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3034 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3036 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3037 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3039 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3044 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3046 case OP_OUTARG_VTRETADDR:
3053 case OP_VOIDCALL_MEMBASE:
3054 case OP_CALL_MEMBASE:
3055 case OP_LCALL_MEMBASE:
3056 case OP_FCALL_MEMBASE:
3057 case OP_VCALL_MEMBASE:
3058 case OP_VOIDCALL_REG:
3062 case OP_VCALL_REG: {
3063 process_call (ctx, bb, &builder, ins);
3064 CHECK_FAILURE (ctx);
3069 LLVMValueRef indexes [2];
3071 LLVMValueRef got_entry_addr;
3074 * FIXME: Can't allocate from the cfg mempool since that is freed if
3075 * the LLVM compile fails.
3077 ji = g_new0 (MonoJumpInfo, 1);
3078 ji->type = (MonoJumpInfoType)ins->inst_i1;
3079 ji->data.target = ins->inst_p0;
3081 ji = mono_aot_patch_info_dup (ji);
3083 ji->next = cfg->patch_info;
3084 cfg->patch_info = ji;
3086 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3087 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3089 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3090 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3091 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3093 // FIXME: This doesn't work right now, because it must be
3094 // paired with an invariant.end, and even then, its only in effect
3095 // inside its basic block
3098 LLVMValueRef args [3];
3099 LLVMValueRef ptr, val;
3101 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3103 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3105 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3109 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3112 case OP_NOT_REACHED:
3113 LLVMBuildUnreachable (builder);
3114 has_terminator = TRUE;
3115 g_assert (bb->block_num < cfg->max_block_num);
3116 ctx->unreachable [bb->block_num] = TRUE;
3117 /* Might have instructions after this */
3119 MonoInst *next = ins->next;
3121 * FIXME: If later code uses the regs defined by these instructions,
3122 * compilation will fail.
3124 MONO_DELETE_INS (bb, next);
3128 MonoInst *var = ins->inst_p0;
3130 values [ins->dreg] = addresses [var->dreg];
3134 LLVMValueRef args [1];
3136 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3137 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3141 LLVMValueRef args [1];
3143 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3144 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3148 LLVMValueRef args [1];
3151 /* This no longer seems to happen */
3153 * LLVM optimizes sqrt(nan) into undefined in
3154 * lib/Analysis/ConstantFolding.cpp
3155 * Also, sqrt(NegativeInfinity) is optimized into 0.
3157 LLVM_FAILURE (ctx, "sqrt");
3159 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3160 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3164 LLVMValueRef args [1];
3166 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3167 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3181 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3182 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3184 switch (ins->opcode) {
3187 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3191 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3195 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3199 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3202 g_assert_not_reached ();
3205 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3208 case OP_ATOMIC_EXCHANGE_I4: {
3209 LLVMValueRef args [2];
3211 g_assert (ins->inst_offset == 0);
3213 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3216 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3219 case OP_ATOMIC_EXCHANGE_I8: {
3220 LLVMValueRef args [2];
3222 g_assert (ins->inst_offset == 0);
3224 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3225 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3226 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3229 case OP_ATOMIC_ADD_NEW_I4: {
3230 LLVMValueRef args [2];
3232 g_assert (ins->inst_offset == 0);
3234 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3236 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3239 case OP_ATOMIC_ADD_NEW_I8: {
3240 LLVMValueRef args [2];
3242 g_assert (ins->inst_offset == 0);
3244 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3245 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3246 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3249 case OP_ATOMIC_CAS_I4:
3250 case OP_ATOMIC_CAS_I8: {
3251 LLVMValueRef args [3];
3254 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3255 t = LLVMInt32Type ();
3257 t = LLVMInt64Type ();
3260 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3262 args [1] = convert (ctx, values [ins->sreg3], t);
3264 args [2] = convert (ctx, values [ins->sreg2], t);
3265 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3268 case OP_MEMORY_BARRIER: {
3269 mono_llvm_build_fence (builder);
3272 case OP_RELAXED_NOP: {
3273 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3274 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3281 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3283 // 257 == FS segment register
3284 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3286 // 256 == GS segment register
3287 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3291 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3293 LLVM_FAILURE (ctx, "opcode tls-get");
3303 case OP_IADD_OVF_UN:
3305 case OP_ISUB_OVF_UN:
3307 case OP_IMUL_OVF_UN:
3308 #if SIZEOF_VOID_P == 8
3310 case OP_LADD_OVF_UN:
3312 case OP_LSUB_OVF_UN:
3314 case OP_LMUL_OVF_UN:
3317 LLVMValueRef args [2], val, ovf, func;
3319 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3320 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3321 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3323 val = LLVMBuildCall (builder, func, args, 2, "");
3324 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3325 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3326 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3327 CHECK_FAILURE (ctx);
3328 builder = ctx->builder;
3334 * We currently model them using arrays. Promotion to local vregs is
3335 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3336 * so we always have an entry in cfg->varinfo for them.
3337 * FIXME: Is this needed ?
3340 MonoClass *klass = ins->klass;
3341 LLVMValueRef args [5];
3345 LLVM_FAILURE (ctx, "!klass");
3349 if (!addresses [ins->dreg])
3350 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3351 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3352 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3353 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3355 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3356 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3357 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3361 case OP_STOREV_MEMBASE:
3362 case OP_LOADV_MEMBASE:
3364 MonoClass *klass = ins->klass;
3365 LLVMValueRef src = NULL, dst, args [5];
3366 gboolean done = FALSE;
3370 LLVM_FAILURE (ctx, "!klass");
3374 switch (ins->opcode) {
3375 case OP_STOREV_MEMBASE:
3376 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3377 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3378 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3381 if (!addresses [ins->sreg1]) {
3383 g_assert (values [ins->sreg1]);
3384 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));
3385 LLVMBuildStore (builder, values [ins->sreg1], dst);
3388 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3389 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3392 case OP_LOADV_MEMBASE:
3393 if (!addresses [ins->dreg])
3394 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3395 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3396 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3399 if (!addresses [ins->sreg1])
3400 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3401 if (!addresses [ins->dreg])
3402 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3403 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3404 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3407 g_assert_not_reached ();
3409 CHECK_FAILURE (ctx);
3416 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3417 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3419 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3420 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3421 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3424 case OP_LLVM_OUTARG_VT:
3425 if (!addresses [ins->sreg1]) {
3426 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3427 g_assert (values [ins->sreg1]);
3428 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3430 addresses [ins->dreg] = addresses [ins->sreg1];
3436 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3438 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3441 case OP_LOADX_MEMBASE: {
3442 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3445 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3446 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3449 case OP_STOREX_MEMBASE: {
3450 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3453 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3454 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3461 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3465 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3471 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3475 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3479 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3483 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3486 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3489 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3492 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3496 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3507 LLVMValueRef v = NULL;
3509 switch (ins->opcode) {
3514 t = LLVMVectorType (LLVMInt32Type (), 4);
3515 rt = LLVMVectorType (LLVMFloatType (), 4);
3521 t = LLVMVectorType (LLVMInt64Type (), 2);
3522 rt = LLVMVectorType (LLVMDoubleType (), 2);
3525 t = LLVMInt32Type ();
3526 rt = LLVMInt32Type ();
3527 g_assert_not_reached ();
3530 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3531 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3532 switch (ins->opcode) {
3535 v = LLVMBuildAnd (builder, lhs, rhs, "");
3539 v = LLVMBuildOr (builder, lhs, rhs, "");
3543 v = LLVMBuildXor (builder, lhs, rhs, "");
3547 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3550 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3574 case OP_PADDB_SAT_UN:
3575 case OP_PADDW_SAT_UN:
3576 case OP_PSUBB_SAT_UN:
3577 case OP_PSUBW_SAT_UN:
3590 case OP_PMULW_HIGH_UN: {
3591 LLVMValueRef args [2];
3596 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3604 case OP_EXTRACTX_U2:
3606 case OP_EXTRACT_U1: {
3608 gboolean zext = FALSE;
3610 t = simd_op_to_llvm_type (ins->opcode);
3612 switch (ins->opcode) {
3620 case OP_EXTRACTX_U2:
3625 t = LLVMInt32Type ();
3626 g_assert_not_reached ();
3629 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3630 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3632 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3641 case OP_EXPAND_R8: {
3642 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3643 LLVMValueRef mask [16], v;
3645 for (i = 0; i < 16; ++i)
3646 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3648 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3650 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3651 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3656 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3659 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3662 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3665 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3668 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3671 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3682 case OP_EXTRACT_MASK:
3689 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3691 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3695 case OP_ICONV_TO_R8_RAW:
3696 /* Same as OP_ICONV_TO_R8 */
3697 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3702 LLVMValueRef args [3];
3706 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3708 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3713 /* This is only used for implementing shifts by non-immediate */
3714 values [ins->dreg] = lhs;
3725 LLVMValueRef args [3];
3728 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3730 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3741 case OP_PSHLQ_REG: {
3742 LLVMValueRef args [3];
3745 args [1] = values [ins->sreg2];
3747 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3754 case OP_PSHUFLEW_LOW:
3755 case OP_PSHUFLEW_HIGH: {
3757 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3758 int i, mask_size = 0;
3759 int imask = ins->inst_c0;
3761 /* Convert the x86 shuffle mask to LLVM's */
3762 switch (ins->opcode) {
3765 mask [0] = ((imask >> 0) & 3);
3766 mask [1] = ((imask >> 2) & 3);
3767 mask [2] = ((imask >> 4) & 3) + 4;
3768 mask [3] = ((imask >> 6) & 3) + 4;
3769 v1 = values [ins->sreg1];
3770 v2 = values [ins->sreg2];
3774 mask [0] = ((imask >> 0) & 1);
3775 mask [1] = ((imask >> 1) & 1) + 2;
3776 v1 = values [ins->sreg1];
3777 v2 = values [ins->sreg2];
3779 case OP_PSHUFLEW_LOW:
3781 mask [0] = ((imask >> 0) & 3);
3782 mask [1] = ((imask >> 2) & 3);
3783 mask [2] = ((imask >> 4) & 3);
3784 mask [3] = ((imask >> 6) & 3);
3789 v1 = values [ins->sreg1];
3790 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3792 case OP_PSHUFLEW_HIGH:
3798 mask [4] = 4 + ((imask >> 0) & 3);
3799 mask [5] = 4 + ((imask >> 2) & 3);
3800 mask [6] = 4 + ((imask >> 4) & 3);
3801 mask [7] = 4 + ((imask >> 6) & 3);
3802 v1 = values [ins->sreg1];
3803 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3807 mask [0] = ((imask >> 0) & 3);
3808 mask [1] = ((imask >> 2) & 3);
3809 mask [2] = ((imask >> 4) & 3);
3810 mask [3] = ((imask >> 6) & 3);
3811 v1 = values [ins->sreg1];
3812 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3815 g_assert_not_reached ();
3817 for (i = 0; i < mask_size; ++i)
3818 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3820 values [ins->dreg] =
3821 LLVMBuildShuffleVector (builder, v1, v2,
3822 LLVMConstVector (mask_values, mask_size), dname);
3826 case OP_UNPACK_LOWB:
3827 case OP_UNPACK_LOWW:
3828 case OP_UNPACK_LOWD:
3829 case OP_UNPACK_LOWQ:
3830 case OP_UNPACK_LOWPS:
3831 case OP_UNPACK_LOWPD:
3832 case OP_UNPACK_HIGHB:
3833 case OP_UNPACK_HIGHW:
3834 case OP_UNPACK_HIGHD:
3835 case OP_UNPACK_HIGHQ:
3836 case OP_UNPACK_HIGHPS:
3837 case OP_UNPACK_HIGHPD: {
3839 LLVMValueRef mask_values [16];
3840 int i, mask_size = 0;
3841 gboolean low = FALSE;
3843 switch (ins->opcode) {
3844 case OP_UNPACK_LOWB:
3848 case OP_UNPACK_LOWW:
3852 case OP_UNPACK_LOWD:
3853 case OP_UNPACK_LOWPS:
3857 case OP_UNPACK_LOWQ:
3858 case OP_UNPACK_LOWPD:
3862 case OP_UNPACK_HIGHB:
3865 case OP_UNPACK_HIGHW:
3868 case OP_UNPACK_HIGHD:
3869 case OP_UNPACK_HIGHPS:
3872 case OP_UNPACK_HIGHQ:
3873 case OP_UNPACK_HIGHPD:
3877 g_assert_not_reached ();
3881 for (i = 0; i < (mask_size / 2); ++i) {
3883 mask [(i * 2) + 1] = mask_size + i;
3886 for (i = 0; i < (mask_size / 2); ++i) {
3887 mask [(i * 2)] = (mask_size / 2) + i;
3888 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3892 for (i = 0; i < mask_size; ++i)
3893 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3895 values [ins->dreg] =
3896 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3897 LLVMConstVector (mask_values, mask_size), dname);
3902 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3903 LLVMValueRef v, val;
3905 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3906 val = LLVMConstNull (t);
3907 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3908 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3910 values [ins->dreg] = val;
3914 case OP_DUPPS_HIGH: {
3915 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3916 LLVMValueRef v1, v2, val;
3919 if (ins->opcode == OP_DUPPS_LOW) {
3920 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3921 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3923 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3924 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3926 val = LLVMConstNull (t);
3927 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3928 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3929 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3930 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3932 values [ins->dreg] = val;
3942 * EXCEPTION HANDLING
3944 case OP_IMPLICIT_EXCEPTION:
3945 /* This marks a place where an implicit exception can happen */
3946 if (bb->region != -1)
3947 LLVM_FAILURE (ctx, "implicit-exception");
3951 MonoMethodSignature *throw_sig;
3952 LLVMValueRef callee, arg;
3953 gboolean rethrow = (ins->opcode == OP_RETHROW);
3954 const char *icall_name;
3956 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3957 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3960 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3961 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3962 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3963 if (cfg->compile_aot) {
3964 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3966 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3970 * LLVM doesn't push the exception argument, so we need a different
3973 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3975 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3979 mono_memory_barrier ();
3981 ctx->lmodule->rethrow = callee;
3983 ctx->lmodule->throw = callee;
3985 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3986 emit_call (ctx, bb, &builder, callee, &arg, 1);
3989 case OP_CALL_HANDLER: {
3991 * We don't 'call' handlers, but instead simply branch to them.
3992 * The code generated by ENDFINALLY will branch back to us.
3994 LLVMBasicBlockRef noex_bb;
3996 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
3998 bb_list = info->call_handler_return_bbs;
4001 * Set the indicator variable for the finally clause.
4003 lhs = info->finally_ind;
4005 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4007 /* Branch to the finally clause */
4008 LLVMBuildBr (builder, info->call_handler_target_bb);
4010 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4011 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4013 builder = ctx->builder = create_builder (ctx);
4014 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4016 bblocks [bb->block_num].end_bblock = noex_bb;
4019 case OP_START_HANDLER: {
4022 case OP_ENDFINALLY: {
4023 LLVMBasicBlockRef resume_bb;
4024 MonoBasicBlock *handler_bb;
4025 LLVMValueRef val, switch_ins, callee;
4029 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4030 g_assert (handler_bb);
4031 info = &bblocks [handler_bb->block_num];
4032 lhs = info->finally_ind;
4035 bb_list = info->call_handler_return_bbs;
4037 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4039 /* Load the finally variable */
4040 val = LLVMBuildLoad (builder, lhs, "");
4042 /* Reset the variable */
4043 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4045 /* Branch to either resume_bb, or to the bblocks in bb_list */
4046 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4048 * The other targets are added at the end to handle OP_CALL_HANDLER
4049 * opcodes processed later.
4051 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4053 builder = ctx->builder = create_builder (ctx);
4054 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4056 if (ctx->cfg->compile_aot) {
4057 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4059 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4061 LLVMBuildCall (builder, callee, NULL, 0, "");
4063 LLVMBuildUnreachable (builder);
4064 has_terminator = TRUE;
4070 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4071 LLVM_FAILURE (ctx, reason);
4076 /* Convert the value to the type required by phi nodes */
4077 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4078 if (!values [ins->dreg])
4080 values [ins->dreg] = addresses [ins->dreg];
4082 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4085 /* Add stores for volatile variables */
4086 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4087 emit_volatile_store (ctx, ins->dreg);
4090 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4091 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4093 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4094 LLVMBuildRetVoid (builder);
4096 if (bb == cfg->bb_entry)
4097 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4106 * mono_llvm_check_method_supported:
4108 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4109 * compiling a method twice.
4112 mono_llvm_check_method_supported (MonoCompile *cfg)
4115 MonoMethodHeader *header = cfg->header;
4116 MonoExceptionClause *clause;
4120 if (cfg->method->save_lmf) {
4121 cfg->exception_message = g_strdup ("lmf");
4122 cfg->disable_llvm = TRUE;
4126 for (i = 0; i < header->num_clauses; ++i) {
4127 clause = &header->clauses [i];
4129 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4131 * FIXME: Some tests still fail with nested clauses.
4133 cfg->exception_message = g_strdup ("nested clauses");
4134 cfg->disable_llvm = TRUE;
4140 if (cfg->method->dynamic) {
4141 cfg->exception_message = g_strdup ("dynamic.");
4142 cfg->disable_llvm = TRUE;
4147 * mono_llvm_emit_method:
4149 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4152 mono_llvm_emit_method (MonoCompile *cfg)
4155 MonoMethodSignature *sig;
4157 LLVMTypeRef method_type;
4158 LLVMValueRef method = NULL;
4160 LLVMValueRef *values;
4161 int i, max_block_num, bb_index;
4162 gboolean last = FALSE;
4163 GPtrArray *phi_values;
4164 LLVMCallInfo *linfo;
4166 LLVMModuleRef module;
4168 GPtrArray *bblock_list;
4169 MonoMethodHeader *header;
4170 MonoExceptionClause *clause;
4174 /* The code below might acquire the loader lock, so use it for global locking */
4175 mono_loader_lock ();
4177 /* Used to communicate with the callbacks */
4178 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4180 ctx = g_new0 (EmitContext, 1);
4182 ctx->mempool = cfg->mempool;
4185 * This maps vregs to the LLVM instruction defining them
4187 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4189 * This maps vregs for volatile variables to the LLVM instruction defining their
4192 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4193 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4194 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4195 phi_values = g_ptr_array_new ();
4197 * This signals whenever the vreg was defined by a phi node with no input vars
4198 * (i.e. all its input bblocks end with NOT_REACHABLE).
4200 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4201 /* Whenever the bblock is unreachable */
4202 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4204 bblock_list = g_ptr_array_new ();
4206 ctx->values = values;
4207 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4209 if (cfg->compile_aot) {
4210 ctx->lmodule = &aot_module;
4211 method_name = mono_aot_get_method_name (cfg);
4212 cfg->llvm_method_name = g_strdup (method_name);
4215 ctx->lmodule = &jit_module;
4216 method_name = mono_method_full_name (cfg->method, TRUE);
4219 module = ctx->module = ctx->lmodule->module;
4223 static int count = 0;
4226 if (getenv ("LLVM_COUNT")) {
4227 if (count == atoi (getenv ("LLVM_COUNT"))) {
4228 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4232 if (count > atoi (getenv ("LLVM_COUNT")))
4233 LLVM_FAILURE (ctx, "");
4238 sig = mono_method_signature (cfg->method);
4241 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4243 CHECK_FAILURE (ctx);
4246 linfo->rgctx_arg = TRUE;
4247 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4248 CHECK_FAILURE (ctx);
4251 * This maps parameter indexes in the original signature to the indexes in
4252 * the LLVM signature.
4254 ctx->pindexes = sinfo.pindexes;
4256 method = LLVMAddFunction (module, method_name, method_type);
4257 ctx->lmethod = method;
4259 #ifdef LLVM_MONO_BRANCH
4260 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4262 LLVMSetLinkage (method, LLVMPrivateLinkage);
4264 LLVMAddFunctionAttr (method, LLVMUWTable);
4266 if (cfg->compile_aot) {
4267 LLVMSetLinkage (method, LLVMInternalLinkage);
4268 LLVMSetVisibility (method, LLVMHiddenVisibility);
4270 LLVMSetLinkage (method, LLVMPrivateLinkage);
4273 if (cfg->method->save_lmf)
4274 LLVM_FAILURE (ctx, "lmf");
4276 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4277 LLVM_FAILURE (ctx, "pinvoke signature");
4279 header = cfg->header;
4280 for (i = 0; i < header->num_clauses; ++i) {
4281 clause = &header->clauses [i];
4282 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4283 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4286 if (linfo->rgctx_arg) {
4287 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4289 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4290 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4291 * CC_X86_64_Mono in X86CallingConv.td.
4293 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4294 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4296 if (cfg->vret_addr) {
4297 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4298 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4301 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4302 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4305 names = g_new (char *, sig->param_count);
4306 mono_method_get_param_names (cfg->method, (const char **) names);
4308 for (i = 0; i < sig->param_count; ++i) {
4311 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4312 if (names [i] && names [i][0] != '\0')
4313 name = g_strdup_printf ("arg_%s", names [i]);
4315 name = g_strdup_printf ("arg_%d", i);
4316 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4318 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4319 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4324 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4325 max_block_num = MAX (max_block_num, bb->block_num);
4326 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4328 /* Add branches between non-consecutive bblocks */
4329 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4330 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4331 bb->next_bb != bb->last_ins->inst_false_bb) {
4333 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4334 inst->opcode = OP_BR;
4335 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4336 mono_bblock_add_inst (bb, inst);
4341 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4342 * was later optimized away, so clear these flags, and add them back for the still
4343 * present OP_LDADDR instructions.
4345 for (i = 0; i < cfg->next_vreg; ++i) {
4348 ins = get_vreg_to_inst (cfg, i);
4349 if (ins && ins != cfg->rgctx_var)
4350 ins->flags &= ~MONO_INST_INDIRECT;
4354 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4356 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4358 LLVMBuilderRef builder;
4360 char dname_buf[128];
4362 builder = create_builder (ctx);
4364 for (ins = bb->code; ins; ins = ins->next) {
4365 switch (ins->opcode) {
4370 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4372 CHECK_FAILURE (ctx);
4374 if (ins->opcode == OP_VPHI) {
4375 /* Treat valuetype PHI nodes as operating on the address itself */
4376 g_assert (ins->klass);
4377 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4381 * Have to precreate these, as they can be referenced by
4382 * earlier instructions.
4384 sprintf (dname_buf, "t%d", ins->dreg);
4386 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4388 if (ins->opcode == OP_VPHI)
4389 ctx->addresses [ins->dreg] = values [ins->dreg];
4391 g_ptr_array_add (phi_values, values [ins->dreg]);
4394 * Set the expected type of the incoming arguments since these have
4395 * to have the same type.
4397 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4398 int sreg1 = ins->inst_phi_args [i + 1];
4401 ctx->vreg_types [sreg1] = phi_type;
4406 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4415 * Create an ordering for bblocks, use the depth first order first, then
4416 * put the exception handling bblocks last.
4418 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4419 bb = cfg->bblocks [bb_index];
4420 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4421 g_ptr_array_add (bblock_list, bb);
4422 bblocks [bb->block_num].added = TRUE;
4426 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4427 if (!bblocks [bb->block_num].added)
4428 g_ptr_array_add (bblock_list, bb);
4432 * Second pass: generate code.
4434 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4435 bb = g_ptr_array_index (bblock_list, bb_index);
4437 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4440 process_bb (ctx, bb);
4441 CHECK_FAILURE (ctx);
4444 /* Add incoming phi values */
4445 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4446 GSList *l, *ins_list;
4448 ins_list = bblocks [bb->block_num].phi_nodes;
4450 for (l = ins_list; l; l = l->next) {
4451 PhiNode *node = l->data;
4452 MonoInst *phi = node->phi;
4453 int sreg1 = node->sreg;
4454 LLVMBasicBlockRef in_bb;
4459 in_bb = get_end_bb (ctx, node->in_bb);
4461 if (ctx->unreachable [node->in_bb->block_num])
4464 g_assert (values [sreg1]);
4466 if (phi->opcode == OP_VPHI) {
4467 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4468 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4470 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4471 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4476 /* Create the SWITCH statements for ENDFINALLY instructions */
4477 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4478 BBInfo *info = &bblocks [bb->block_num];
4480 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4481 LLVMValueRef switch_ins = l->data;
4482 GSList *bb_list = info->call_handler_return_bbs;
4484 for (i = 0; i < g_slist_length (bb_list); ++i)
4485 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4489 if (cfg->verbose_level > 1)
4490 mono_llvm_dump_value (method);
4492 mark_as_used (module, method);
4494 if (cfg->compile_aot) {
4495 /* Don't generate native code, keep the LLVM IR */
4496 if (cfg->compile_aot && cfg->verbose_level)
4497 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4499 //LLVMVerifyFunction(method, 0);
4501 mono_llvm_optimize_method (method);
4503 if (cfg->verbose_level > 1)
4504 mono_llvm_dump_value (method);
4506 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4508 /* Set by emit_cb */
4509 g_assert (cfg->code_len);
4511 /* FIXME: Free the LLVM IL for the function */
4519 /* Need to add unused phi nodes as they can be referenced by other values */
4520 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4521 LLVMBuilderRef builder;
4523 builder = create_builder (ctx);
4524 LLVMPositionBuilderAtEnd (builder, phi_bb);
4526 for (i = 0; i < phi_values->len; ++i) {
4527 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4528 if (LLVMGetInstructionParent (v) == NULL)
4529 LLVMInsertIntoBuilder (builder, v);
4532 LLVMDeleteFunction (method);
4537 g_free (ctx->addresses);
4538 g_free (ctx->vreg_types);
4539 g_free (ctx->vreg_cli_types);
4540 g_free (ctx->pindexes);
4541 g_free (ctx->is_dead);
4542 g_free (ctx->unreachable);
4543 g_ptr_array_free (phi_values, TRUE);
4544 g_free (ctx->bblocks);
4545 g_hash_table_destroy (ctx->region_to_handler);
4546 g_free (method_name);
4547 g_ptr_array_free (bblock_list, TRUE);
4549 for (l = ctx->builders; l; l = l->next) {
4550 LLVMBuilderRef builder = l->data;
4551 LLVMDisposeBuilder (builder);
4556 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4558 mono_loader_unlock ();
4562 * mono_llvm_emit_call:
4564 * Same as mono_arch_emit_call () for LLVM.
4567 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4570 MonoMethodSignature *sig;
4571 int i, n, stack_size;
4576 sig = call->signature;
4577 n = sig->param_count + sig->hasthis;
4579 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4581 if (cfg->disable_llvm)
4584 if (sig->call_convention == MONO_CALL_VARARG) {
4585 cfg->exception_message = g_strdup ("varargs");
4586 cfg->disable_llvm = TRUE;
4589 for (i = 0; i < n; ++i) {
4592 ainfo = call->cinfo->args + i;
4594 in = call->args [i];
4596 /* Simply remember the arguments */
4597 switch (ainfo->storage) {
4599 case LLVMArgInFPReg: {
4600 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4602 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4603 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4604 ins->dreg = mono_alloc_freg (cfg);
4606 MONO_INST_NEW (cfg, ins, OP_MOVE);
4607 ins->dreg = mono_alloc_ireg (cfg);
4609 ins->sreg1 = in->dreg;
4612 case LLVMArgVtypeByVal:
4613 case LLVMArgVtypeInReg:
4614 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4615 ins->dreg = mono_alloc_ireg (cfg);
4616 ins->sreg1 = in->dreg;
4617 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4620 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4621 cfg->exception_message = g_strdup ("ainfo->storage");
4622 cfg->disable_llvm = TRUE;
4626 if (!cfg->disable_llvm) {
4627 MONO_ADD_INS (cfg->cbb, ins);
4628 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4633 static unsigned char*
4634 alloc_cb (LLVMValueRef function, int size)
4638 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4642 return mono_domain_code_reserve (cfg->domain, size);
4644 return mono_domain_code_reserve (mono_domain_get (), size);
4649 emitted_cb (LLVMValueRef function, void *start, void *end)
4653 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4655 cfg->code_len = (guint8*)end - (guint8*)start;
4659 exception_cb (void *data)
4662 MonoJitExceptionInfo *ei;
4663 guint32 ei_len, i, j, nested_len, nindex;
4664 gpointer *type_info;
4665 int this_reg, this_offset;
4667 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4671 * data points to a DWARF FDE structure, convert it to our unwind format and
4673 * An alternative would be to save it directly, and modify our unwinder to work
4676 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);
4678 /* Count nested clauses */
4680 for (i = 0; i < ei_len; ++i) {
4681 for (j = 0; j < ei_len; ++j) {
4682 gint32 cindex1 = *(gint32*)type_info [i];
4683 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4684 gint32 cindex2 = *(gint32*)type_info [j];
4685 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4687 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4693 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4694 cfg->llvm_ex_info_len = ei_len + nested_len;
4695 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4696 /* Fill the rest of the information from the type info */
4697 for (i = 0; i < ei_len; ++i) {
4698 gint32 clause_index = *(gint32*)type_info [i];
4699 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4701 cfg->llvm_ex_info [i].flags = clause->flags;
4702 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4706 * For nested clauses, the LLVM produced exception info associates the try interval with
4707 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4709 /* FIXME: These should be order with the normal clauses */
4711 for (i = 0; i < ei_len; ++i) {
4712 for (j = 0; j < ei_len; ++j) {
4713 gint32 cindex1 = *(gint32*)type_info [i];
4714 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4715 gint32 cindex2 = *(gint32*)type_info [j];
4716 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4718 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4720 * The try interval comes from the nested clause, everything else from the
4723 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4724 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4725 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4730 g_assert (nindex == ei_len + nested_len);
4731 cfg->llvm_this_reg = this_reg;
4732 cfg->llvm_this_offset = this_offset;
4734 /* type_info [i] is cfg mempool allocated, no need to free it */
4741 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4743 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4747 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4749 LLVMTypeRef param_types [4];
4751 param_types [0] = param_type1;
4752 param_types [1] = param_type2;
4754 AddFunc (module, name, ret_type, param_types, 2);
4758 add_intrinsics (LLVMModuleRef module)
4760 /* Emit declarations of instrinsics */
4762 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4763 * type doesn't seem to do any locking.
4766 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4768 memset_param_count = 5;
4769 memset_func_name = "llvm.memset.p0i8.i32";
4771 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4775 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4777 memcpy_param_count = 5;
4778 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4780 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4784 LLVMTypeRef params [] = { LLVMDoubleType () };
4786 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4787 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4788 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4790 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4791 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4795 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4796 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4798 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4799 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4800 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4801 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4802 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4803 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4807 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4808 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4810 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4811 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4812 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4813 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4814 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4815 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4819 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4820 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4821 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4823 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4825 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4830 LLVMTypeRef arg_types [2];
4831 LLVMTypeRef ret_type;
4833 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4834 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4835 ret_type = LLVMInt32Type ();
4837 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4839 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4842 /* SSE intrinsics */
4844 LLVMTypeRef ret_type, arg_types [16];
4847 ret_type = type_to_simd_type (MONO_TYPE_I4);
4848 arg_types [0] = ret_type;
4849 arg_types [1] = ret_type;
4850 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4851 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4852 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4854 ret_type = type_to_simd_type (MONO_TYPE_I2);
4855 arg_types [0] = ret_type;
4856 arg_types [1] = ret_type;
4857 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4858 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4859 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4860 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4861 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4862 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4863 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4864 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4865 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4866 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4867 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4869 ret_type = type_to_simd_type (MONO_TYPE_I1);
4870 arg_types [0] = ret_type;
4871 arg_types [1] = ret_type;
4872 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4873 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4874 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4875 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4876 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4877 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4878 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4879 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4880 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4882 ret_type = type_to_simd_type (MONO_TYPE_I8);
4883 arg_types [0] = ret_type;
4884 arg_types [1] = ret_type;
4885 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4887 ret_type = type_to_simd_type (MONO_TYPE_R8);
4888 arg_types [0] = ret_type;
4889 arg_types [1] = ret_type;
4890 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4891 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4892 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4893 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4894 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4896 ret_type = type_to_simd_type (MONO_TYPE_R4);
4897 arg_types [0] = ret_type;
4898 arg_types [1] = ret_type;
4899 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4900 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4901 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4902 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4903 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4906 ret_type = type_to_simd_type (MONO_TYPE_I1);
4907 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4908 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4909 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4910 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4911 ret_type = type_to_simd_type (MONO_TYPE_I2);
4912 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4913 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4914 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4915 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4918 ret_type = type_to_simd_type (MONO_TYPE_R8);
4919 arg_types [0] = ret_type;
4920 arg_types [1] = ret_type;
4921 arg_types [2] = LLVMInt8Type ();
4922 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4923 ret_type = type_to_simd_type (MONO_TYPE_R4);
4924 arg_types [0] = ret_type;
4925 arg_types [1] = ret_type;
4926 arg_types [2] = LLVMInt8Type ();
4927 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4929 /* Conversion ops */
4930 ret_type = type_to_simd_type (MONO_TYPE_R8);
4931 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4932 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4933 ret_type = type_to_simd_type (MONO_TYPE_R4);
4934 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4935 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4936 ret_type = type_to_simd_type (MONO_TYPE_I4);
4937 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4938 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4939 ret_type = type_to_simd_type (MONO_TYPE_I4);
4940 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4941 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4942 ret_type = type_to_simd_type (MONO_TYPE_R4);
4943 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4944 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4945 ret_type = type_to_simd_type (MONO_TYPE_R8);
4946 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4947 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4949 ret_type = type_to_simd_type (MONO_TYPE_I4);
4950 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4951 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4952 ret_type = type_to_simd_type (MONO_TYPE_I4);
4953 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4954 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4957 ret_type = type_to_simd_type (MONO_TYPE_R8);
4958 arg_types [0] = ret_type;
4959 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
4960 ret_type = type_to_simd_type (MONO_TYPE_R4);
4961 arg_types [0] = ret_type;
4962 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
4963 ret_type = type_to_simd_type (MONO_TYPE_R4);
4964 arg_types [0] = ret_type;
4965 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
4966 ret_type = type_to_simd_type (MONO_TYPE_R4);
4967 arg_types [0] = ret_type;
4968 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
4971 ret_type = type_to_simd_type (MONO_TYPE_I2);
4972 arg_types [0] = ret_type;
4973 arg_types [1] = LLVMInt32Type ();
4974 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
4975 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
4976 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
4977 ret_type = type_to_simd_type (MONO_TYPE_I4);
4978 arg_types [0] = ret_type;
4979 arg_types [1] = LLVMInt32Type ();
4980 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
4981 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
4982 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
4983 ret_type = type_to_simd_type (MONO_TYPE_I8);
4984 arg_types [0] = ret_type;
4985 arg_types [1] = LLVMInt32Type ();
4986 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
4987 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
4990 ret_type = LLVMInt32Type ();
4991 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
4992 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
4995 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
4997 /* Load/Store intrinsics */
4999 LLVMTypeRef arg_types [5];
5003 for (i = 1; i <= 8; i *= 2) {
5004 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5005 arg_types [1] = LLVMInt32Type ();
5006 arg_types [2] = LLVMInt1Type ();
5007 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5008 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5010 arg_types [0] = LLVMIntType (i * 8);
5011 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5012 arg_types [2] = LLVMInt32Type ();
5013 arg_types [3] = LLVMInt1Type ();
5014 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5015 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5021 mono_llvm_init (void)
5023 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5027 init_jit_module (void)
5029 MonoJitICallInfo *info;
5031 if (jit_module_inited)
5034 mono_loader_lock ();
5036 if (jit_module_inited) {
5037 mono_loader_unlock ();
5041 jit_module.module = LLVMModuleCreateWithName ("mono");
5043 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5045 add_intrinsics (jit_module.module);
5047 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5049 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5051 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5053 jit_module_inited = TRUE;
5055 mono_loader_unlock ();
5059 mono_llvm_cleanup (void)
5062 mono_llvm_dispose_ee (ee);
5064 if (jit_module.llvm_types)
5065 g_hash_table_destroy (jit_module.llvm_types);
5067 if (aot_module.module)
5068 LLVMDisposeModule (aot_module.module);
5070 LLVMContextDispose (LLVMGetGlobalContext ());
5074 mono_llvm_create_aot_module (const char *got_symbol)
5076 /* Delete previous module */
5077 if (aot_module.plt_entries)
5078 g_hash_table_destroy (aot_module.plt_entries);
5079 if (aot_module.module)
5080 LLVMDisposeModule (aot_module.module);
5082 memset (&aot_module, 0, sizeof (aot_module));
5084 aot_module.module = LLVMModuleCreateWithName ("aot");
5085 aot_module.got_symbol = got_symbol;
5087 add_intrinsics (aot_module.module);
5091 * We couldn't compute the type of the LLVM global representing the got because
5092 * its size is only known after all the methods have been emitted. So create
5093 * a dummy variable, and replace all uses it with the real got variable when
5094 * its size is known in mono_llvm_emit_aot_module ().
5097 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5099 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5100 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5103 /* Add a dummy personality function */
5105 LLVMBasicBlockRef lbb;
5106 LLVMBuilderRef lbuilder;
5107 LLVMValueRef personality;
5109 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5110 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5111 lbb = LLVMAppendBasicBlock (personality, "BB0");
5112 lbuilder = LLVMCreateBuilder ();
5113 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5114 LLVMBuildRetVoid (lbuilder);
5117 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5118 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5122 * Emit the aot module into the LLVM bitcode file FILENAME.
5125 mono_llvm_emit_aot_module (const char *filename, int got_size)
5127 LLVMTypeRef got_type;
5128 LLVMValueRef real_got;
5131 * Create the real got variable and replace all uses of the dummy variable with
5134 got_type = LLVMArrayType (IntPtrType (), got_size);
5135 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5136 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5137 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5139 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5141 mark_as_used (aot_module.module, real_got);
5143 /* Delete the dummy got so it doesn't become a global */
5144 LLVMDeleteGlobal (aot_module.got_var);
5150 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5151 g_assert_not_reached ();
5156 LLVMWriteBitcodeToFile (aot_module.module, filename);
5161 - Emit LLVM IR from the mono IR using the LLVM C API.
5162 - The original arch specific code remains, so we can fall back to it if we run
5163 into something we can't handle.
5167 A partial list of issues:
5168 - Handling of opcodes which can throw exceptions.
5170 In the mono JIT, these are implemented using code like this:
5177 push throw_pos - method
5178 call <exception trampoline>
5180 The problematic part is push throw_pos - method, which cannot be represented
5181 in the LLVM IR, since it does not support label values.
5182 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5183 be implemented in JIT mode ?
5184 -> a possible but slower implementation would use the normal exception
5185 throwing code but it would need to control the placement of the throw code
5186 (it needs to be exactly after the compare+branch).
5187 -> perhaps add a PC offset intrinsics ?
5189 - efficient implementation of .ovf opcodes.
5191 These are currently implemented as:
5192 <ins which sets the condition codes>
5195 Some overflow opcodes are now supported by LLVM SVN.
5197 - exception handling, unwinding.
5198 - SSA is disabled for methods with exception handlers
5199 - How to obtain unwind info for LLVM compiled methods ?
5200 -> this is now solved by converting the unwind info generated by LLVM
5202 - LLVM uses the c++ exception handling framework, while we use our home grown
5203 code, and couldn't use the c++ one:
5204 - its not supported under VC++, other exotic platforms.
5205 - it might be impossible to support filter clauses with it.
5209 The trampolines need a predictable call sequence, since they need to disasm
5210 the calling code to obtain register numbers / offsets.
5212 LLVM currently generates this code in non-JIT mode:
5213 mov -0x98(%rax),%eax
5215 Here, the vtable pointer is lost.
5216 -> solution: use one vtable trampoline per class.
5218 - passing/receiving the IMT pointer/RGCTX.
5219 -> solution: pass them as normal arguments ?
5223 LLVM does not allow the specification of argument registers etc. This means
5224 that all calls are made according to the platform ABI.
5226 - passing/receiving vtypes.
5228 Vtypes passed/received in registers are handled by the front end by using
5229 a signature with scalar arguments, and loading the parts of the vtype into those
5232 Vtypes passed on the stack are handled using the 'byval' attribute.
5236 Supported though alloca, we need to emit the load/store code.
5240 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5241 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5242 This is made easier because the IR is already in SSA form.
5243 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5244 types are frequently used incorrectly.
5249 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5250 append the AOT data structures to that file. For methods which cannot be
5251 handled by LLVM, the normal JIT compiled versions are used.
5254 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5255 * - each bblock should end with a branch
5256 * - setting the return value, making cfg->ret non-volatile
5257 * - avoid some transformations in the JIT which make it harder for us to generate
5259 * - use pointer types to help optimizations.