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 LLVMPointerType (IntPtrType (), 0);
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 && IS_LLVM_MONO_BRANCH) {
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 if (!IS_LLVM_MONO_BRANCH)
1290 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1291 md_arg = LLVMMDString ("mono", 4);
1292 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1298 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1302 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1304 MonoCompile *cfg = ctx->cfg;
1306 LLVMBuilderRef builder = *builder_ref;
1309 clause_index = get_handler_clause (cfg, bb);
1311 if (clause_index != -1) {
1312 MonoMethodHeader *header = cfg->header;
1313 MonoExceptionClause *ec = &header->clauses [clause_index];
1314 MonoBasicBlock *tblock;
1315 LLVMBasicBlockRef ex_bb, noex_bb;
1318 * Have to use an invoke instead of a call, branching to the
1319 * handler bblock of the clause containing this bblock.
1322 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1324 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1327 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1329 ex_bb = get_bb (ctx, tblock);
1331 noex_bb = gen_bb (ctx, "NOEX_BB");
1334 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1336 builder = ctx->builder = create_builder (ctx);
1337 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1339 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1341 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1342 ctx->builder = builder;
1345 *builder_ref = ctx->builder;
1351 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1353 const char *intrins_name;
1354 LLVMValueRef args [16], res;
1355 LLVMTypeRef addr_type;
1357 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1359 * We handle loads which can fault by calling a mono specific intrinsic
1360 * using an invoke, so they are handled properly inside try blocks.
1361 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1362 * are marked with IntrReadArgMem.
1366 intrins_name = "llvm.mono.load.i8.p0i8";
1369 intrins_name = "llvm.mono.load.i16.p0i16";
1372 intrins_name = "llvm.mono.load.i32.p0i32";
1375 intrins_name = "llvm.mono.load.i64.p0i64";
1378 g_assert_not_reached ();
1381 addr_type = LLVMTypeOf (addr);
1382 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1383 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1386 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1387 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1388 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1390 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1391 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1392 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1393 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1400 * We emit volatile loads for loads which can fault, because otherwise
1401 * LLVM will generate invalid code when encountering a load from a
1404 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1406 /* Mark it with a custom metadata */
1409 set_metadata_flag (res, "mono.faulting.load");
1417 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1419 const char *intrins_name;
1420 LLVMValueRef args [16];
1422 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1425 intrins_name = "llvm.mono.store.i8.p0i8";
1428 intrins_name = "llvm.mono.store.i16.p0i16";
1431 intrins_name = "llvm.mono.store.i32.p0i32";
1434 intrins_name = "llvm.mono.store.i64.p0i64";
1437 g_assert_not_reached ();
1440 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1441 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1442 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1447 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1448 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1449 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1451 LLVMBuildStore (*builder_ref, value, addr);
1456 * emit_cond_system_exception:
1458 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1459 * Might set the ctx exception.
1462 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1464 LLVMBasicBlockRef ex_bb, noex_bb;
1465 LLVMBuilderRef builder;
1466 MonoClass *exc_class;
1467 LLVMValueRef args [2];
1469 ex_bb = gen_bb (ctx, "EX_BB");
1470 noex_bb = gen_bb (ctx, "NOEX_BB");
1472 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1474 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1475 g_assert (exc_class);
1477 /* Emit exception throwing code */
1478 builder = create_builder (ctx);
1479 LLVMPositionBuilderAtEnd (builder, ex_bb);
1481 if (!ctx->lmodule->throw_corlib_exception) {
1482 LLVMValueRef callee;
1484 const char *icall_name;
1486 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1487 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1488 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1489 if (IS_LLVM_MONO_BRANCH) {
1490 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1491 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1493 icall_name = "llvm_throw_corlib_exception_trampoline";
1494 throw_sig->params [1] = &mono_get_int32_class ()->byval_arg;
1496 sig = sig_to_llvm_sig (ctx, throw_sig);
1498 if (ctx->cfg->compile_aot) {
1499 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1501 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1504 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1505 * - On x86, LLVM generated code doesn't push the arguments
1506 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1507 * arguments, not a pc offset.
1509 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1512 mono_memory_barrier ();
1513 ctx->lmodule->throw_corlib_exception = callee;
1517 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1519 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1521 if (IS_LLVM_MONO_BRANCH) {
1523 * The LLVM mono branch contains changes so a block address can be passed as an
1524 * argument to a call.
1526 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1527 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1530 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1531 * otherwise only the line numbers in stack traces are incorrect.
1533 if (bb->region != -1 && !IS_LLVM_MONO_BRANCH)
1534 LLVM_FAILURE (ctx, "system-ex-in-region");
1536 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1537 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1540 LLVMBuildUnreachable (builder);
1542 ctx->builder = create_builder (ctx);
1543 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1545 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1555 * emit_reg_to_vtype:
1557 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1560 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1564 size = get_vtype_size (t);
1566 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1567 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1570 for (j = 0; j < 2; ++j) {
1571 LLVMValueRef index [2], addr;
1572 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1573 LLVMTypeRef part_type;
1575 if (ainfo->pair_storage [j] == LLVMArgNone)
1578 part_type = LLVMIntType (part_size * 8);
1579 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1580 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1581 addr = LLVMBuildGEP (builder, address, index, 1, "");
1583 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1584 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1585 addr = LLVMBuildGEP (builder, address, index, 2, "");
1587 switch (ainfo->pair_storage [j]) {
1589 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1594 g_assert_not_reached ();
1597 size -= sizeof (gpointer);
1602 * emit_vtype_to_reg:
1604 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1605 * into REGS, and the number of registers into NREGS.
1608 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1613 size = get_vtype_size (t);
1615 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1616 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1619 for (j = 0; j < 2; ++j) {
1620 LLVMValueRef index [2], addr;
1621 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1623 if (ainfo->pair_storage [j] == LLVMArgNone)
1626 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1627 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1628 addr = LLVMBuildGEP (builder, address, index, 1, "");
1630 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1631 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1632 addr = LLVMBuildGEP (builder, address, index, 2, "");
1634 switch (ainfo->pair_storage [j]) {
1636 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1641 g_assert_not_reached ();
1643 size -= sizeof (gpointer);
1650 build_alloca (EmitContext *ctx, MonoType *t)
1652 MonoClass *k = mono_class_from_mono_type (t);
1655 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1658 align = mono_class_min_align (k);
1660 /* Sometimes align is not a power of 2 */
1661 while (mono_is_power_of_two (align) == -1)
1665 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1666 * get executed every time control reaches them.
1668 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1670 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1671 return ctx->last_alloca;
1675 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1678 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1680 LLVMTypeRef used_type;
1681 LLVMValueRef used, used_elem;
1683 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1684 used = LLVMAddGlobal (module, used_type, "llvm.used");
1685 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1686 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1687 LLVMSetLinkage (used, LLVMAppendingLinkage);
1688 LLVMSetSection (used, "llvm.metadata");
1694 * Emit code to load/convert arguments.
1697 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1700 MonoCompile *cfg = ctx->cfg;
1701 MonoMethodSignature *sig = ctx->sig;
1702 LLVMCallInfo *linfo = ctx->linfo;
1705 ctx->alloca_builder = create_builder (ctx);
1708 * Handle indirect/volatile variables by allocating memory for them
1709 * using 'alloca', and storing their address in a temporary.
1711 for (i = 0; i < cfg->num_varinfo; ++i) {
1712 MonoInst *var = cfg->varinfo [i];
1715 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1716 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1717 CHECK_FAILURE (ctx);
1718 /* Could be already created by an OP_VPHI */
1719 if (!ctx->addresses [var->dreg])
1720 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1721 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1725 for (i = 0; i < sig->param_count; ++i) {
1726 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1727 int reg = cfg->args [i + sig->hasthis]->dreg;
1729 if (ainfo->storage == LLVMArgVtypeInReg) {
1730 LLVMValueRef regs [2];
1733 * Emit code to save the argument from the registers to
1734 * the real argument.
1736 pindex = ctx->pindexes [i];
1737 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1738 if (ainfo->pair_storage [1] != LLVMArgNone)
1739 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1743 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1745 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1747 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1748 /* Treat these as normal values */
1749 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1751 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1752 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1754 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1755 /* Treat these as normal values */
1756 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1759 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1764 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1766 emit_volatile_store (ctx, cfg->args [0]->dreg);
1767 for (i = 0; i < sig->param_count; ++i)
1768 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1769 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1771 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1772 LLVMValueRef this_alloc;
1775 * The exception handling code needs the location where the this argument was
1776 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1777 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1778 * location into the LSDA.
1780 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1781 /* This volatile store will keep the alloca alive */
1782 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1784 set_metadata_flag (this_alloc, "mono.this");
1787 if (cfg->rgctx_var) {
1788 LLVMValueRef rgctx_alloc, store;
1791 * We handle the rgctx arg similarly to the this pointer.
1793 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1794 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1795 /* This volatile store will keep the alloca alive */
1796 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1798 set_metadata_flag (rgctx_alloc, "mono.this");
1802 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1803 * it needs to continue normally, or return back to the exception handling system.
1805 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1806 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1807 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1808 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1812 sprintf (name, "finally_ind_bb%d", bb->block_num);
1813 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1814 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1816 ctx->bblocks [bb->block_num].finally_ind = val;
1819 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1820 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1821 * LLVM optimizer passes.
1823 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1824 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1832 /* Have to export this for AOT */
1834 mono_personality (void);
1837 mono_personality (void)
1840 g_assert_not_reached ();
1844 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1846 MonoCompile *cfg = ctx->cfg;
1847 LLVMModuleRef module = ctx->module;
1848 LLVMValueRef *values = ctx->values;
1849 LLVMValueRef *addresses = ctx->addresses;
1850 MonoCallInst *call = (MonoCallInst*)ins;
1851 MonoMethodSignature *sig = call->signature;
1852 LLVMValueRef callee = NULL, lcall;
1854 LLVMCallInfo *cinfo;
1858 LLVMTypeRef llvm_sig;
1860 gboolean virtual, calli;
1861 LLVMBuilderRef builder = *builder_ref;
1864 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1865 LLVM_FAILURE (ctx, "non-default callconv");
1867 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
1868 LLVM_FAILURE (ctx, "rgctx reg in call");
1870 if (call->rgctx_reg && !IS_LLVM_MONO_BRANCH) {
1872 * It might be possible to support this by creating a static rgctx trampoline, but
1873 * common_call_trampoline () would patch callsites to call the trampoline, which
1874 * would be incorrect if the rgctx arg is computed dynamically.
1876 LLVM_FAILURE (ctx, "rgctx reg");
1879 cinfo = call->cinfo;
1880 if (call->rgctx_arg_reg)
1881 cinfo->rgctx_arg = TRUE;
1882 if (call->imt_arg_reg)
1883 cinfo->imt_arg = TRUE;
1885 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1887 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1888 CHECK_FAILURE (ctx);
1890 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);
1891 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);
1893 /* FIXME: Avoid creating duplicate methods */
1895 if (ins->flags & MONO_INST_HAS_METHOD) {
1899 if (cfg->compile_aot) {
1900 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1902 LLVM_FAILURE (ctx, "can't encode patch");
1904 callee = LLVMAddFunction (module, "", llvm_sig);
1907 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1909 LLVMAddGlobalMapping (ee, callee, target);
1914 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1920 memset (&ji, 0, sizeof (ji));
1921 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1922 ji.data.target = info->name;
1924 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1926 if (cfg->compile_aot) {
1927 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1929 LLVM_FAILURE (ctx, "can't encode patch");
1931 callee = LLVMAddFunction (module, "", llvm_sig);
1932 target = (gpointer)mono_icall_get_wrapper (info);
1933 LLVMAddGlobalMapping (ee, callee, target);
1936 if (cfg->compile_aot) {
1938 if (cfg->abs_patches) {
1939 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1941 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1943 LLVM_FAILURE (ctx, "can't encode patch");
1947 LLVM_FAILURE (ctx, "aot");
1949 callee = LLVMAddFunction (module, "", llvm_sig);
1951 if (cfg->abs_patches) {
1952 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1955 * FIXME: Some trampolines might have
1956 * their own calling convention on some platforms.
1958 #ifndef TARGET_AMD64
1959 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)
1960 LLVM_FAILURE (ctx, "trampoline with own cconv");
1962 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1963 LLVMAddGlobalMapping (ee, callee, target);
1967 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1973 int size = sizeof (gpointer);
1976 g_assert (ins->inst_offset % size == 0);
1977 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1980 * When using the llvm mono branch, we can support IMT directly, otherwise
1981 * we need to call a trampoline.
1983 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
1984 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1985 if (cfg->compile_aot) {
1986 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
1987 imt_tramp->method = call->method;
1988 imt_tramp->vt_offset = call->inst.inst_offset;
1990 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
1992 callee = LLVMAddFunction (module, "", llvm_sig);
1993 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
1994 LLVMAddGlobalMapping (ee, callee, target);
1997 /* No support for passing the IMT argument */
1998 LLVM_FAILURE (ctx, "imt");
2001 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2004 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2006 if (ins->flags & MONO_INST_HAS_METHOD) {
2011 * Collect and convert arguments
2013 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
2014 args = alloca (len);
2015 memset (args, 0, len);
2016 l = call->out_ireg_args;
2018 if (IS_LLVM_MONO_BRANCH) {
2019 if (call->rgctx_arg_reg) {
2020 g_assert (values [call->rgctx_arg_reg]);
2021 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
2023 if (call->imt_arg_reg) {
2024 g_assert (values [call->imt_arg_reg]);
2025 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
2030 if (!addresses [call->inst.dreg])
2031 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2032 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2035 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2038 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2042 pindex = sinfo.this_arg_pindex;
2044 pindex = sinfo.pindexes [i - 1];
2046 pindex = sinfo.pindexes [i];
2049 regpair = (guint32)(gssize)(l->data);
2050 reg = regpair & 0xffffff;
2051 args [pindex] = values [reg];
2052 if (ainfo->storage == LLVMArgVtypeInReg) {
2054 LLVMValueRef regs [2];
2059 g_assert (addresses [reg]);
2061 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2062 for (j = 0; j < nregs; ++j)
2063 args [pindex ++] = regs [j];
2066 // FIXME: Get rid of the VMOVE
2067 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2068 g_assert (addresses [reg]);
2069 args [pindex] = addresses [reg];
2071 g_assert (args [pindex]);
2072 if (i == 0 && sig->hasthis)
2073 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2075 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2081 // FIXME: Align call sites
2087 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2089 #ifdef LLVM_MONO_BRANCH
2091 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2093 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2094 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2096 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2097 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2099 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2101 if (call->rgctx_arg_reg)
2102 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2103 if (call->imt_arg_reg)
2104 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2107 /* Add byval attributes if needed */
2108 for (i = 0; i < sig->param_count; ++i) {
2109 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2111 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2112 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2117 * Convert the result
2119 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2120 LLVMValueRef regs [2];
2122 if (!addresses [ins->dreg])
2123 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2125 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2126 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2127 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2129 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2130 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2131 /* If the method returns an unsigned value, need to zext it */
2133 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));
2136 *builder_ref = ctx->builder;
2138 g_free (sinfo.pindexes);
2146 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2148 MonoCompile *cfg = ctx->cfg;
2149 MonoMethodSignature *sig = ctx->sig;
2150 LLVMValueRef method = ctx->lmethod;
2151 LLVMValueRef *values = ctx->values;
2152 LLVMValueRef *addresses = ctx->addresses;
2154 LLVMCallInfo *linfo = ctx->linfo;
2155 LLVMModuleRef module = ctx->module;
2156 BBInfo *bblocks = ctx->bblocks;
2158 LLVMBasicBlockRef cbb;
2159 LLVMBuilderRef builder;
2160 gboolean has_terminator;
2162 LLVMValueRef lhs, rhs;
2164 cbb = get_bb (ctx, bb);
2165 builder = create_builder (ctx);
2166 ctx->builder = builder;
2167 LLVMPositionBuilderAtEnd (builder, cbb);
2169 if (bb == cfg->bb_entry)
2170 emit_entry_bb (ctx, builder);
2171 CHECK_FAILURE (ctx);
2173 if (bb->flags & BB_EXCEPTION_HANDLER) {
2175 LLVMValueRef personality;
2176 LLVMBasicBlockRef target_bb;
2178 static gint32 mapping_inited;
2179 static int ti_generator;
2182 LLVMValueRef type_info;
2185 if (!bblocks [bb->block_num].invoke_target) {
2187 * LLVM asserts if llvm.eh.selector is called from a bblock which
2188 * doesn't have an invoke pointing at it.
2189 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2191 LLVM_FAILURE (ctx, "handler without invokes");
2194 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2196 if (cfg->compile_aot) {
2197 /* Use a dummy personality function */
2198 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2199 g_assert (personality);
2201 personality = LLVMGetNamedFunction (module, "mono_personality");
2202 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2203 LLVMAddGlobalMapping (ee, personality, mono_personality);
2206 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2208 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2211 * Create the type info
2213 sprintf (ti_name, "type_info_%d", ti_generator);
2216 if (cfg->compile_aot) {
2217 /* decode_eh_frame () in aot-runtime.c will decode this */
2218 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2219 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2221 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2222 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2225 * Enabling this causes llc to crash:
2226 * http://llvm.org/bugs/show_bug.cgi?id=6102
2228 //LLVM_FAILURE (ctx, "aot+clauses");
2231 * After the cfg mempool is freed, the type info will point to stale memory,
2232 * but this is not a problem, since we decode it once in exception_cb during
2235 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2236 *(gint32*)ti = clause_index;
2238 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2240 LLVMAddGlobalMapping (ee, type_info, ti);
2244 LLVMTypeRef members [2], ret_type;
2245 LLVMValueRef landing_pad;
2247 members [0] = i8ptr;
2248 members [1] = LLVMInt32Type ();
2249 ret_type = LLVMStructType (members, 2, FALSE);
2251 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2252 LLVMAddClause (landing_pad, type_info);
2254 /* Store the exception into the exvar */
2255 if (bb->in_scount == 1) {
2256 g_assert (bb->in_scount == 1);
2257 exvar = bb->in_stack [0];
2259 // FIXME: This is shared with filter clauses ?
2260 g_assert (!values [exvar->dreg]);
2262 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2263 emit_volatile_store (ctx, exvar->dreg);
2267 /* Start a new bblock which CALL_HANDLER can branch to */
2268 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2270 LLVMBuildBr (builder, target_bb);
2272 ctx->builder = builder = create_builder (ctx);
2273 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2275 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2279 has_terminator = FALSE;
2280 for (ins = bb->code; ins; ins = ins->next) {
2281 const char *spec = LLVM_INS_INFO (ins->opcode);
2283 char dname_buf [128];
2286 /* There could be instructions after a terminator, skip them */
2289 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2290 sprintf (dname_buf, "t%d", ins->dreg);
2294 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2295 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2297 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2298 lhs = emit_volatile_load (ctx, ins->sreg1);
2300 /* It is ok for SETRET to have an uninitialized argument */
2301 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2302 LLVM_FAILURE (ctx, "sreg1");
2303 lhs = values [ins->sreg1];
2309 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2310 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2311 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2312 rhs = emit_volatile_load (ctx, ins->sreg2);
2314 if (!values [ins->sreg2])
2315 LLVM_FAILURE (ctx, "sreg2");
2316 rhs = values [ins->sreg2];
2322 //mono_print_ins (ins);
2323 switch (ins->opcode) {
2326 case OP_LIVERANGE_START:
2327 case OP_LIVERANGE_END:
2330 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2333 #if SIZEOF_VOID_P == 4
2334 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2336 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2340 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2343 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2346 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2347 has_terminator = TRUE;
2353 LLVMBasicBlockRef new_bb;
2354 LLVMBuilderRef new_builder;
2356 // The default branch is already handled
2357 // FIXME: Handle it here
2359 /* Start new bblock */
2360 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2361 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2363 lhs = convert (ctx, lhs, LLVMInt32Type ());
2364 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2365 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2366 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2368 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2371 new_builder = create_builder (ctx);
2372 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2373 LLVMBuildUnreachable (new_builder);
2375 has_terminator = TRUE;
2376 g_assert (!ins->next);
2382 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2383 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2384 LLVMValueRef part1, retval;
2387 size = get_vtype_size (sig->ret);
2389 g_assert (addresses [ins->sreg1]);
2391 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2392 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2394 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2396 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2398 LLVMBuildRet (builder, retval);
2402 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2403 LLVMBuildRetVoid (builder);
2407 if (!lhs || ctx->is_dead [ins->sreg1]) {
2409 * The method did not set its return value, probably because it
2410 * ends with a throw.
2413 LLVMBuildRetVoid (builder);
2415 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2417 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2419 has_terminator = TRUE;
2425 case OP_ICOMPARE_IMM:
2426 case OP_LCOMPARE_IMM:
2427 case OP_COMPARE_IMM: {
2431 if (ins->next->opcode == OP_NOP)
2434 if (ins->next->opcode == OP_BR)
2435 /* The comparison result is not needed */
2438 rel = mono_opcode_to_cond (ins->next->opcode);
2440 if (ins->opcode == OP_ICOMPARE_IMM) {
2441 lhs = convert (ctx, lhs, LLVMInt32Type ());
2442 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2444 if (ins->opcode == OP_LCOMPARE_IMM) {
2445 lhs = convert (ctx, lhs, LLVMInt64Type ());
2446 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2448 if (ins->opcode == OP_LCOMPARE) {
2449 lhs = convert (ctx, lhs, LLVMInt64Type ());
2450 rhs = convert (ctx, rhs, LLVMInt64Type ());
2452 if (ins->opcode == OP_ICOMPARE) {
2453 lhs = convert (ctx, lhs, LLVMInt32Type ());
2454 rhs = convert (ctx, rhs, LLVMInt32Type ());
2458 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2459 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2460 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2461 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2464 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2465 if (ins->opcode == OP_FCOMPARE)
2466 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2467 else if (ins->opcode == OP_COMPARE_IMM)
2468 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2469 else if (ins->opcode == OP_LCOMPARE_IMM) {
2470 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2471 /* The immediate is encoded in two fields */
2472 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2473 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2475 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2478 else if (ins->opcode == OP_COMPARE)
2479 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2481 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2483 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2484 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2486 * If the target bb contains PHI instructions, LLVM requires
2487 * two PHI entries for this bblock, while we only generate one.
2488 * So convert this to an unconditional bblock. (bxc #171).
2490 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2492 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2494 has_terminator = TRUE;
2495 } else if (MONO_IS_SETCC (ins->next)) {
2496 sprintf (dname_buf, "t%d", ins->next->dreg);
2498 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2500 /* Add stores for volatile variables */
2501 emit_volatile_store (ctx, ins->next->dreg);
2502 } else if (MONO_IS_COND_EXC (ins->next)) {
2503 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2504 CHECK_FAILURE (ctx);
2505 builder = ctx->builder;
2507 LLVM_FAILURE (ctx, "next");
2521 rel = mono_opcode_to_cond (ins->opcode);
2523 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2524 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2532 gboolean empty = TRUE;
2534 /* Check that all input bblocks really branch to us */
2535 for (i = 0; i < bb->in_count; ++i) {
2536 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2537 ins->inst_phi_args [i + 1] = -1;
2543 /* LLVM doesn't like phi instructions with zero operands */
2544 ctx->is_dead [ins->dreg] = TRUE;
2548 /* Created earlier, insert it now */
2549 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2551 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2552 int sreg1 = ins->inst_phi_args [i + 1];
2556 * Count the number of times the incoming bblock branches to us,
2557 * since llvm requires a separate entry for each.
2559 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2560 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2563 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2564 if (switch_ins->inst_many_bb [j] == bb)
2571 /* Remember for later */
2572 for (j = 0; j < count; ++j) {
2573 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2576 node->in_bb = bb->in_bb [i];
2578 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);
2588 values [ins->dreg] = lhs;
2591 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2594 values [ins->dreg] = lhs;
2596 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2598 * This is added by the spilling pass in case of the JIT,
2599 * but we have to do it ourselves.
2601 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2635 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2636 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2638 switch (ins->opcode) {
2641 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2645 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2649 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2653 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2657 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2661 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2665 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2668 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2672 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2676 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2680 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2684 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2688 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2692 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2696 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2699 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2702 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2706 g_assert_not_reached ();
2713 case OP_IREM_UN_IMM:
2715 case OP_IDIV_UN_IMM:
2721 case OP_ISHR_UN_IMM:
2730 case OP_LSHR_UN_IMM:
2738 if (spec [MONO_INST_SRC1] == 'l') {
2739 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2741 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2744 #if SIZEOF_VOID_P == 4
2745 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2746 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2749 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2750 lhs = convert (ctx, lhs, IntPtrType ());
2751 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2752 switch (ins->opcode) {
2756 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2760 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2764 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2768 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2770 case OP_IDIV_UN_IMM:
2771 case OP_LDIV_UN_IMM:
2772 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2776 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2778 case OP_IREM_UN_IMM:
2779 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2784 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2788 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2792 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2797 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2802 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2804 case OP_ISHR_UN_IMM:
2805 /* This is used to implement conv.u4, so the lhs could be an i8 */
2806 lhs = convert (ctx, lhs, LLVMInt32Type ());
2807 imm = convert (ctx, imm, LLVMInt32Type ());
2808 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2810 case OP_LSHR_UN_IMM:
2811 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2814 g_assert_not_reached ();
2819 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2822 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2825 lhs = convert (ctx, lhs, LLVMDoubleType ());
2826 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2829 guint32 v = 0xffffffff;
2830 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2834 guint64 v = 0xffffffffffffffffLL;
2835 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2838 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2840 LLVMValueRef v1, v2;
2842 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2843 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2844 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2849 case OP_ICONV_TO_I1:
2850 case OP_ICONV_TO_I2:
2851 case OP_ICONV_TO_I4:
2852 case OP_ICONV_TO_U1:
2853 case OP_ICONV_TO_U2:
2854 case OP_ICONV_TO_U4:
2855 case OP_LCONV_TO_I1:
2856 case OP_LCONV_TO_I2:
2857 case OP_LCONV_TO_U1:
2858 case OP_LCONV_TO_U2:
2859 case OP_LCONV_TO_U4: {
2862 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);
2864 /* Have to do two casts since our vregs have type int */
2865 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2867 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2869 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2872 case OP_ICONV_TO_I8:
2873 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2875 case OP_ICONV_TO_U8:
2876 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2878 case OP_FCONV_TO_I4:
2879 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2881 case OP_FCONV_TO_I1:
2882 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2884 case OP_FCONV_TO_U1:
2885 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2887 case OP_FCONV_TO_I2:
2888 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2890 case OP_FCONV_TO_U2:
2891 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2893 case OP_FCONV_TO_I8:
2894 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2897 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2899 case OP_ICONV_TO_R8:
2900 case OP_LCONV_TO_R8:
2901 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2903 case OP_LCONV_TO_R_UN:
2904 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2906 #if SIZEOF_VOID_P == 4
2909 case OP_LCONV_TO_I4:
2910 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2912 case OP_ICONV_TO_R4:
2913 case OP_LCONV_TO_R4:
2914 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2915 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2917 case OP_FCONV_TO_R4:
2918 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2919 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2922 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2925 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2928 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2930 case OP_LOCALLOC_IMM: {
2933 guint32 size = ins->inst_imm;
2934 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2936 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2938 if (ins->flags & MONO_INST_INIT) {
2939 LLVMValueRef args [5];
2942 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2943 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2944 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2945 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2946 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2949 values [ins->dreg] = v;
2953 LLVMValueRef v, size;
2955 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), "");
2957 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2959 if (ins->flags & MONO_INST_INIT) {
2960 LLVMValueRef args [5];
2963 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2965 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2966 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2967 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2969 values [ins->dreg] = v;
2973 case OP_LOADI1_MEMBASE:
2974 case OP_LOADU1_MEMBASE:
2975 case OP_LOADI2_MEMBASE:
2976 case OP_LOADU2_MEMBASE:
2977 case OP_LOADI4_MEMBASE:
2978 case OP_LOADU4_MEMBASE:
2979 case OP_LOADI8_MEMBASE:
2980 case OP_LOADR4_MEMBASE:
2981 case OP_LOADR8_MEMBASE:
2982 case OP_LOAD_MEMBASE:
2990 LLVMValueRef base, index, addr;
2992 gboolean sext = FALSE, zext = FALSE;
2993 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2995 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3000 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)) {
3001 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3006 if (ins->inst_offset == 0) {
3008 } else if (ins->inst_offset % size != 0) {
3009 /* Unaligned load */
3010 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3011 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3013 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3014 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3018 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3020 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3022 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
3024 * These will signal LLVM that these loads do not alias any stores, and
3025 * they can't fail, allowing them to be hoisted out of loops.
3027 set_metadata_flag (values [ins->dreg], "mono.noalias");
3028 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3032 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3034 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3035 else if (ins->opcode == OP_LOADR4_MEMBASE)
3036 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3040 case OP_STOREI1_MEMBASE_REG:
3041 case OP_STOREI2_MEMBASE_REG:
3042 case OP_STOREI4_MEMBASE_REG:
3043 case OP_STOREI8_MEMBASE_REG:
3044 case OP_STORER4_MEMBASE_REG:
3045 case OP_STORER8_MEMBASE_REG:
3046 case OP_STORE_MEMBASE_REG: {
3048 LLVMValueRef index, addr;
3050 gboolean sext = FALSE, zext = FALSE;
3051 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3053 if (!values [ins->inst_destbasereg])
3054 LLVM_FAILURE (ctx, "inst_destbasereg");
3056 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3058 if (ins->inst_offset % size != 0) {
3059 /* Unaligned store */
3060 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3061 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3063 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3064 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3066 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3070 case OP_STOREI1_MEMBASE_IMM:
3071 case OP_STOREI2_MEMBASE_IMM:
3072 case OP_STOREI4_MEMBASE_IMM:
3073 case OP_STOREI8_MEMBASE_IMM:
3074 case OP_STORE_MEMBASE_IMM: {
3076 LLVMValueRef index, addr;
3078 gboolean sext = FALSE, zext = FALSE;
3079 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3081 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3083 if (ins->inst_offset % size != 0) {
3084 /* Unaligned store */
3085 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3086 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3088 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3089 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3091 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3096 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3098 case OP_OUTARG_VTRETADDR:
3105 case OP_VOIDCALL_MEMBASE:
3106 case OP_CALL_MEMBASE:
3107 case OP_LCALL_MEMBASE:
3108 case OP_FCALL_MEMBASE:
3109 case OP_VCALL_MEMBASE:
3110 case OP_VOIDCALL_REG:
3114 case OP_VCALL_REG: {
3115 process_call (ctx, bb, &builder, ins);
3116 CHECK_FAILURE (ctx);
3121 LLVMValueRef indexes [2];
3123 LLVMValueRef got_entry_addr;
3126 * FIXME: Can't allocate from the cfg mempool since that is freed if
3127 * the LLVM compile fails.
3129 ji = g_new0 (MonoJumpInfo, 1);
3130 ji->type = (MonoJumpInfoType)ins->inst_i1;
3131 ji->data.target = ins->inst_p0;
3133 ji = mono_aot_patch_info_dup (ji);
3135 ji->next = cfg->patch_info;
3136 cfg->patch_info = ji;
3138 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3139 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3141 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3142 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3143 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3145 // FIXME: This doesn't work right now, because it must be
3146 // paired with an invariant.end, and even then, its only in effect
3147 // inside its basic block
3150 LLVMValueRef args [3];
3151 LLVMValueRef ptr, val;
3153 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3155 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3157 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3161 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3164 case OP_NOT_REACHED:
3165 LLVMBuildUnreachable (builder);
3166 has_terminator = TRUE;
3167 g_assert (bb->block_num < cfg->max_block_num);
3168 ctx->unreachable [bb->block_num] = TRUE;
3169 /* Might have instructions after this */
3171 MonoInst *next = ins->next;
3173 * FIXME: If later code uses the regs defined by these instructions,
3174 * compilation will fail.
3176 MONO_DELETE_INS (bb, next);
3180 MonoInst *var = ins->inst_p0;
3182 values [ins->dreg] = addresses [var->dreg];
3186 LLVMValueRef args [1];
3188 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3189 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3193 LLVMValueRef args [1];
3195 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3196 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3200 LLVMValueRef args [1];
3203 /* This no longer seems to happen */
3205 * LLVM optimizes sqrt(nan) into undefined in
3206 * lib/Analysis/ConstantFolding.cpp
3207 * Also, sqrt(NegativeInfinity) is optimized into 0.
3209 LLVM_FAILURE (ctx, "sqrt");
3212 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3216 LLVMValueRef args [1];
3219 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3233 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3234 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3236 switch (ins->opcode) {
3239 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3243 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3247 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3251 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3254 g_assert_not_reached ();
3257 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3260 case OP_ATOMIC_EXCHANGE_I4: {
3261 LLVMValueRef args [2];
3263 g_assert (ins->inst_offset == 0);
3265 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3268 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3271 case OP_ATOMIC_EXCHANGE_I8: {
3272 LLVMValueRef args [2];
3274 g_assert (ins->inst_offset == 0);
3276 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3277 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3278 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3281 case OP_ATOMIC_ADD_NEW_I4: {
3282 LLVMValueRef args [2];
3284 g_assert (ins->inst_offset == 0);
3286 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3288 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3291 case OP_ATOMIC_ADD_NEW_I8: {
3292 LLVMValueRef args [2];
3294 g_assert (ins->inst_offset == 0);
3296 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3297 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3298 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3301 case OP_ATOMIC_CAS_I4:
3302 case OP_ATOMIC_CAS_I8: {
3303 LLVMValueRef args [3];
3306 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3307 t = LLVMInt32Type ();
3309 t = LLVMInt64Type ();
3312 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3314 args [1] = convert (ctx, values [ins->sreg3], t);
3316 args [2] = convert (ctx, values [ins->sreg2], t);
3317 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3320 case OP_MEMORY_BARRIER: {
3322 /* Not yet supported by llc on arm */
3323 LLVM_FAILURE (ctx, "memory-barrier+arm");
3325 mono_llvm_build_fence (builder);
3328 case OP_RELAXED_NOP: {
3329 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3330 if (IS_LLVM_MONO_BRANCH)
3331 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3333 /* No way to get LLVM to emit this */
3334 LLVM_FAILURE (ctx, "relaxed_nop");
3341 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3343 // 257 == FS segment register
3344 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3346 // 256 == GS segment register
3347 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3351 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3353 LLVM_FAILURE (ctx, "opcode tls-get");
3363 case OP_IADD_OVF_UN:
3365 case OP_ISUB_OVF_UN:
3367 case OP_IMUL_OVF_UN:
3368 #if SIZEOF_VOID_P == 8
3370 case OP_LADD_OVF_UN:
3372 case OP_LSUB_OVF_UN:
3374 case OP_LMUL_OVF_UN:
3377 LLVMValueRef args [2], val, ovf, func;
3379 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3380 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3381 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3383 val = LLVMBuildCall (builder, func, args, 2, "");
3384 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3385 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3386 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3387 CHECK_FAILURE (ctx);
3388 builder = ctx->builder;
3394 * We currently model them using arrays. Promotion to local vregs is
3395 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3396 * so we always have an entry in cfg->varinfo for them.
3397 * FIXME: Is this needed ?
3400 MonoClass *klass = ins->klass;
3401 LLVMValueRef args [5];
3405 LLVM_FAILURE (ctx, "!klass");
3409 if (!addresses [ins->dreg])
3410 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3411 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3412 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3413 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3415 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3416 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3417 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3421 case OP_STOREV_MEMBASE:
3422 case OP_LOADV_MEMBASE:
3424 MonoClass *klass = ins->klass;
3425 LLVMValueRef src = NULL, dst, args [5];
3426 gboolean done = FALSE;
3430 LLVM_FAILURE (ctx, "!klass");
3434 switch (ins->opcode) {
3435 case OP_STOREV_MEMBASE:
3436 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3437 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3438 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3441 if (!addresses [ins->sreg1]) {
3443 g_assert (values [ins->sreg1]);
3444 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));
3445 LLVMBuildStore (builder, values [ins->sreg1], dst);
3448 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3449 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3452 case OP_LOADV_MEMBASE:
3453 if (!addresses [ins->dreg])
3454 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3455 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3456 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3459 if (!addresses [ins->sreg1])
3460 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3461 if (!addresses [ins->dreg])
3462 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3463 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3464 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3467 g_assert_not_reached ();
3469 CHECK_FAILURE (ctx);
3476 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3477 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3479 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3480 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3481 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3484 case OP_LLVM_OUTARG_VT:
3485 if (!addresses [ins->sreg1]) {
3486 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3487 g_assert (values [ins->sreg1]);
3488 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3490 addresses [ins->dreg] = addresses [ins->sreg1];
3496 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3498 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3501 case OP_LOADX_MEMBASE: {
3502 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3505 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3506 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3509 case OP_STOREX_MEMBASE: {
3510 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3513 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3514 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3521 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3525 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3531 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3535 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3539 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3543 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3546 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3549 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3552 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3556 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3567 LLVMValueRef v = NULL;
3569 switch (ins->opcode) {
3574 t = LLVMVectorType (LLVMInt32Type (), 4);
3575 rt = LLVMVectorType (LLVMFloatType (), 4);
3581 t = LLVMVectorType (LLVMInt64Type (), 2);
3582 rt = LLVMVectorType (LLVMDoubleType (), 2);
3585 t = LLVMInt32Type ();
3586 rt = LLVMInt32Type ();
3587 g_assert_not_reached ();
3590 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3591 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3592 switch (ins->opcode) {
3595 v = LLVMBuildAnd (builder, lhs, rhs, "");
3599 v = LLVMBuildOr (builder, lhs, rhs, "");
3603 v = LLVMBuildXor (builder, lhs, rhs, "");
3607 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3610 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3634 case OP_PADDB_SAT_UN:
3635 case OP_PADDW_SAT_UN:
3636 case OP_PSUBB_SAT_UN:
3637 case OP_PSUBW_SAT_UN:
3650 case OP_PMULW_HIGH_UN: {
3651 LLVMValueRef args [2];
3656 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3664 case OP_EXTRACTX_U2:
3666 case OP_EXTRACT_U1: {
3668 gboolean zext = FALSE;
3670 t = simd_op_to_llvm_type (ins->opcode);
3672 switch (ins->opcode) {
3680 case OP_EXTRACTX_U2:
3685 t = LLVMInt32Type ();
3686 g_assert_not_reached ();
3689 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3690 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3692 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3701 case OP_EXPAND_R8: {
3702 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3703 LLVMValueRef mask [16], v;
3705 for (i = 0; i < 16; ++i)
3706 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3708 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3710 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3711 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3716 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3719 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3722 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3725 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3728 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3731 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3742 case OP_EXTRACT_MASK:
3749 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3751 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3755 case OP_ICONV_TO_R8_RAW:
3756 /* Same as OP_ICONV_TO_R8 */
3757 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3762 LLVMValueRef args [3];
3766 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3768 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3773 /* This is only used for implementing shifts by non-immediate */
3774 values [ins->dreg] = lhs;
3785 LLVMValueRef args [3];
3788 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3790 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3801 case OP_PSHLQ_REG: {
3802 LLVMValueRef args [3];
3805 args [1] = values [ins->sreg2];
3807 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3814 case OP_PSHUFLEW_LOW:
3815 case OP_PSHUFLEW_HIGH: {
3817 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3818 int i, mask_size = 0;
3819 int imask = ins->inst_c0;
3821 /* Convert the x86 shuffle mask to LLVM's */
3822 switch (ins->opcode) {
3825 mask [0] = ((imask >> 0) & 3);
3826 mask [1] = ((imask >> 2) & 3);
3827 mask [2] = ((imask >> 4) & 3) + 4;
3828 mask [3] = ((imask >> 6) & 3) + 4;
3829 v1 = values [ins->sreg1];
3830 v2 = values [ins->sreg2];
3834 mask [0] = ((imask >> 0) & 1);
3835 mask [1] = ((imask >> 1) & 1) + 2;
3836 v1 = values [ins->sreg1];
3837 v2 = values [ins->sreg2];
3839 case OP_PSHUFLEW_LOW:
3841 mask [0] = ((imask >> 0) & 3);
3842 mask [1] = ((imask >> 2) & 3);
3843 mask [2] = ((imask >> 4) & 3);
3844 mask [3] = ((imask >> 6) & 3);
3849 v1 = values [ins->sreg1];
3850 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3852 case OP_PSHUFLEW_HIGH:
3858 mask [4] = 4 + ((imask >> 0) & 3);
3859 mask [5] = 4 + ((imask >> 2) & 3);
3860 mask [6] = 4 + ((imask >> 4) & 3);
3861 mask [7] = 4 + ((imask >> 6) & 3);
3862 v1 = values [ins->sreg1];
3863 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3867 mask [0] = ((imask >> 0) & 3);
3868 mask [1] = ((imask >> 2) & 3);
3869 mask [2] = ((imask >> 4) & 3);
3870 mask [3] = ((imask >> 6) & 3);
3871 v1 = values [ins->sreg1];
3872 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3875 g_assert_not_reached ();
3877 for (i = 0; i < mask_size; ++i)
3878 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3880 values [ins->dreg] =
3881 LLVMBuildShuffleVector (builder, v1, v2,
3882 LLVMConstVector (mask_values, mask_size), dname);
3886 case OP_UNPACK_LOWB:
3887 case OP_UNPACK_LOWW:
3888 case OP_UNPACK_LOWD:
3889 case OP_UNPACK_LOWQ:
3890 case OP_UNPACK_LOWPS:
3891 case OP_UNPACK_LOWPD:
3892 case OP_UNPACK_HIGHB:
3893 case OP_UNPACK_HIGHW:
3894 case OP_UNPACK_HIGHD:
3895 case OP_UNPACK_HIGHQ:
3896 case OP_UNPACK_HIGHPS:
3897 case OP_UNPACK_HIGHPD: {
3899 LLVMValueRef mask_values [16];
3900 int i, mask_size = 0;
3901 gboolean low = FALSE;
3903 switch (ins->opcode) {
3904 case OP_UNPACK_LOWB:
3908 case OP_UNPACK_LOWW:
3912 case OP_UNPACK_LOWD:
3913 case OP_UNPACK_LOWPS:
3917 case OP_UNPACK_LOWQ:
3918 case OP_UNPACK_LOWPD:
3922 case OP_UNPACK_HIGHB:
3925 case OP_UNPACK_HIGHW:
3928 case OP_UNPACK_HIGHD:
3929 case OP_UNPACK_HIGHPS:
3932 case OP_UNPACK_HIGHQ:
3933 case OP_UNPACK_HIGHPD:
3937 g_assert_not_reached ();
3941 for (i = 0; i < (mask_size / 2); ++i) {
3943 mask [(i * 2) + 1] = mask_size + i;
3946 for (i = 0; i < (mask_size / 2); ++i) {
3947 mask [(i * 2)] = (mask_size / 2) + i;
3948 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3952 for (i = 0; i < mask_size; ++i)
3953 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3955 values [ins->dreg] =
3956 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3957 LLVMConstVector (mask_values, mask_size), dname);
3962 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3963 LLVMValueRef v, val;
3965 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3966 val = LLVMConstNull (t);
3967 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3968 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3970 values [ins->dreg] = val;
3974 case OP_DUPPS_HIGH: {
3975 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3976 LLVMValueRef v1, v2, val;
3979 if (ins->opcode == OP_DUPPS_LOW) {
3980 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3981 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3983 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3984 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3986 val = LLVMConstNull (t);
3987 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3988 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3989 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3990 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3992 values [ins->dreg] = val;
4002 * EXCEPTION HANDLING
4004 case OP_IMPLICIT_EXCEPTION:
4005 /* This marks a place where an implicit exception can happen */
4006 if (bb->region != -1)
4007 LLVM_FAILURE (ctx, "implicit-exception");
4011 MonoMethodSignature *throw_sig;
4012 LLVMValueRef callee, arg;
4013 gboolean rethrow = (ins->opcode == OP_RETHROW);
4014 const char *icall_name;
4016 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4017 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4020 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4021 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4022 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4023 if (cfg->compile_aot) {
4024 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4026 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4030 * LLVM doesn't push the exception argument, so we need a different
4033 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4035 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4039 mono_memory_barrier ();
4041 ctx->lmodule->rethrow = callee;
4043 ctx->lmodule->throw = callee;
4045 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4046 emit_call (ctx, bb, &builder, callee, &arg, 1);
4049 case OP_CALL_HANDLER: {
4051 * We don't 'call' handlers, but instead simply branch to them.
4052 * The code generated by ENDFINALLY will branch back to us.
4054 LLVMBasicBlockRef noex_bb;
4056 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4058 bb_list = info->call_handler_return_bbs;
4061 * Set the indicator variable for the finally clause.
4063 lhs = info->finally_ind;
4065 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4067 /* Branch to the finally clause */
4068 LLVMBuildBr (builder, info->call_handler_target_bb);
4070 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4071 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4073 builder = ctx->builder = create_builder (ctx);
4074 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4076 bblocks [bb->block_num].end_bblock = noex_bb;
4079 case OP_START_HANDLER: {
4082 case OP_ENDFINALLY: {
4083 LLVMBasicBlockRef resume_bb;
4084 MonoBasicBlock *handler_bb;
4085 LLVMValueRef val, switch_ins, callee;
4089 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4090 g_assert (handler_bb);
4091 info = &bblocks [handler_bb->block_num];
4092 lhs = info->finally_ind;
4095 bb_list = info->call_handler_return_bbs;
4097 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4099 /* Load the finally variable */
4100 val = LLVMBuildLoad (builder, lhs, "");
4102 /* Reset the variable */
4103 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4105 /* Branch to either resume_bb, or to the bblocks in bb_list */
4106 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4108 * The other targets are added at the end to handle OP_CALL_HANDLER
4109 * opcodes processed later.
4111 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4113 builder = ctx->builder = create_builder (ctx);
4114 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4116 if (ctx->cfg->compile_aot) {
4117 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4119 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4121 LLVMBuildCall (builder, callee, NULL, 0, "");
4123 LLVMBuildUnreachable (builder);
4124 has_terminator = TRUE;
4130 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4131 LLVM_FAILURE (ctx, reason);
4136 /* Convert the value to the type required by phi nodes */
4137 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4138 if (!values [ins->dreg])
4140 values [ins->dreg] = addresses [ins->dreg];
4142 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4145 /* Add stores for volatile variables */
4146 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4147 emit_volatile_store (ctx, ins->dreg);
4150 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4151 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4153 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4154 LLVMBuildRetVoid (builder);
4156 if (bb == cfg->bb_entry)
4157 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4166 * mono_llvm_check_method_supported:
4168 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4169 * compiling a method twice.
4172 mono_llvm_check_method_supported (MonoCompile *cfg)
4175 MonoMethodHeader *header = cfg->header;
4176 MonoExceptionClause *clause;
4180 if (cfg->generic_sharing_context && !IS_LLVM_MONO_BRANCH) {
4181 /* No way to obtain location info for this/rgctx */
4182 cfg->exception_message = g_strdup ("gshared");
4183 cfg->disable_llvm = TRUE;
4186 if (cfg->method->save_lmf) {
4187 cfg->exception_message = g_strdup ("lmf");
4188 cfg->disable_llvm = TRUE;
4192 for (i = 0; i < header->num_clauses; ++i) {
4193 clause = &header->clauses [i];
4195 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4197 * FIXME: Some tests still fail with nested clauses.
4199 cfg->exception_message = g_strdup ("nested clauses");
4200 cfg->disable_llvm = TRUE;
4206 if (cfg->method->dynamic) {
4207 cfg->exception_message = g_strdup ("dynamic.");
4208 cfg->disable_llvm = TRUE;
4213 * mono_llvm_emit_method:
4215 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4218 mono_llvm_emit_method (MonoCompile *cfg)
4221 MonoMethodSignature *sig;
4223 LLVMTypeRef method_type;
4224 LLVMValueRef method = NULL;
4226 LLVMValueRef *values;
4227 int i, max_block_num, bb_index;
4228 gboolean last = FALSE;
4229 GPtrArray *phi_values;
4230 LLVMCallInfo *linfo;
4232 LLVMModuleRef module;
4234 GPtrArray *bblock_list;
4235 MonoMethodHeader *header;
4236 MonoExceptionClause *clause;
4240 /* The code below might acquire the loader lock, so use it for global locking */
4241 mono_loader_lock ();
4243 /* Used to communicate with the callbacks */
4244 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4246 ctx = g_new0 (EmitContext, 1);
4248 ctx->mempool = cfg->mempool;
4251 * This maps vregs to the LLVM instruction defining them
4253 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4255 * This maps vregs for volatile variables to the LLVM instruction defining their
4258 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4259 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4260 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4261 phi_values = g_ptr_array_new ();
4263 * This signals whenever the vreg was defined by a phi node with no input vars
4264 * (i.e. all its input bblocks end with NOT_REACHABLE).
4266 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4267 /* Whenever the bblock is unreachable */
4268 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4270 bblock_list = g_ptr_array_new ();
4272 ctx->values = values;
4273 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4275 if (cfg->compile_aot) {
4276 ctx->lmodule = &aot_module;
4277 method_name = mono_aot_get_method_name (cfg);
4278 cfg->llvm_method_name = g_strdup (method_name);
4281 ctx->lmodule = &jit_module;
4282 method_name = mono_method_full_name (cfg->method, TRUE);
4285 module = ctx->module = ctx->lmodule->module;
4289 static int count = 0;
4292 if (getenv ("LLVM_COUNT")) {
4293 if (count == atoi (getenv ("LLVM_COUNT"))) {
4294 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4298 if (count > atoi (getenv ("LLVM_COUNT")))
4299 LLVM_FAILURE (ctx, "");
4304 sig = mono_method_signature (cfg->method);
4307 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4309 CHECK_FAILURE (ctx);
4311 if (cfg->rgctx_var) {
4312 if (IS_LLVM_MONO_BRANCH)
4313 linfo->rgctx_arg = TRUE;
4315 LLVM_FAILURE (ctx, "rgctx arg");
4317 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4318 CHECK_FAILURE (ctx);
4321 * This maps parameter indexes in the original signature to the indexes in
4322 * the LLVM signature.
4324 ctx->pindexes = sinfo.pindexes;
4326 method = LLVMAddFunction (module, method_name, method_type);
4327 ctx->lmethod = method;
4329 #ifdef LLVM_MONO_BRANCH
4330 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4332 LLVMSetLinkage (method, LLVMPrivateLinkage);
4334 LLVMAddFunctionAttr (method, LLVMUWTable);
4336 if (cfg->compile_aot) {
4337 LLVMSetLinkage (method, LLVMInternalLinkage);
4338 LLVMSetVisibility (method, LLVMHiddenVisibility);
4340 LLVMSetLinkage (method, LLVMPrivateLinkage);
4343 if (cfg->method->save_lmf)
4344 LLVM_FAILURE (ctx, "lmf");
4346 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4347 LLVM_FAILURE (ctx, "pinvoke signature");
4349 header = cfg->header;
4350 for (i = 0; i < header->num_clauses; ++i) {
4351 clause = &header->clauses [i];
4352 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4353 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4356 if (linfo->rgctx_arg) {
4357 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4359 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4360 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4361 * CC_X86_64_Mono in X86CallingConv.td.
4363 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4364 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4366 if (cfg->vret_addr) {
4367 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4368 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4371 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4372 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4375 names = g_new (char *, sig->param_count);
4376 mono_method_get_param_names (cfg->method, (const char **) names);
4378 for (i = 0; i < sig->param_count; ++i) {
4381 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4382 if (names [i] && names [i][0] != '\0')
4383 name = g_strdup_printf ("arg_%s", names [i]);
4385 name = g_strdup_printf ("arg_%d", i);
4386 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4388 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4389 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4394 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4395 max_block_num = MAX (max_block_num, bb->block_num);
4396 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4398 /* Add branches between non-consecutive bblocks */
4399 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4400 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4401 bb->next_bb != bb->last_ins->inst_false_bb) {
4403 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4404 inst->opcode = OP_BR;
4405 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4406 mono_bblock_add_inst (bb, inst);
4411 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4412 * was later optimized away, so clear these flags, and add them back for the still
4413 * present OP_LDADDR instructions.
4415 for (i = 0; i < cfg->next_vreg; ++i) {
4418 ins = get_vreg_to_inst (cfg, i);
4419 if (ins && ins != cfg->rgctx_var)
4420 ins->flags &= ~MONO_INST_INDIRECT;
4424 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4426 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4428 LLVMBuilderRef builder;
4430 char dname_buf[128];
4432 builder = create_builder (ctx);
4434 for (ins = bb->code; ins; ins = ins->next) {
4435 switch (ins->opcode) {
4440 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4442 CHECK_FAILURE (ctx);
4444 if (ins->opcode == OP_VPHI) {
4445 /* Treat valuetype PHI nodes as operating on the address itself */
4446 g_assert (ins->klass);
4447 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4451 * Have to precreate these, as they can be referenced by
4452 * earlier instructions.
4454 sprintf (dname_buf, "t%d", ins->dreg);
4456 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4458 if (ins->opcode == OP_VPHI)
4459 ctx->addresses [ins->dreg] = values [ins->dreg];
4461 g_ptr_array_add (phi_values, values [ins->dreg]);
4464 * Set the expected type of the incoming arguments since these have
4465 * to have the same type.
4467 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4468 int sreg1 = ins->inst_phi_args [i + 1];
4471 ctx->vreg_types [sreg1] = phi_type;
4476 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4485 * Create an ordering for bblocks, use the depth first order first, then
4486 * put the exception handling bblocks last.
4488 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4489 bb = cfg->bblocks [bb_index];
4490 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4491 g_ptr_array_add (bblock_list, bb);
4492 bblocks [bb->block_num].added = TRUE;
4496 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4497 if (!bblocks [bb->block_num].added)
4498 g_ptr_array_add (bblock_list, bb);
4502 * Second pass: generate code.
4504 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4505 bb = g_ptr_array_index (bblock_list, bb_index);
4507 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4510 process_bb (ctx, bb);
4511 CHECK_FAILURE (ctx);
4514 /* Add incoming phi values */
4515 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4516 GSList *l, *ins_list;
4518 ins_list = bblocks [bb->block_num].phi_nodes;
4520 for (l = ins_list; l; l = l->next) {
4521 PhiNode *node = l->data;
4522 MonoInst *phi = node->phi;
4523 int sreg1 = node->sreg;
4524 LLVMBasicBlockRef in_bb;
4529 in_bb = get_end_bb (ctx, node->in_bb);
4531 if (ctx->unreachable [node->in_bb->block_num])
4534 g_assert (values [sreg1]);
4536 if (phi->opcode == OP_VPHI) {
4537 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4538 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4540 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4541 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4546 /* Create the SWITCH statements for ENDFINALLY instructions */
4547 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4548 BBInfo *info = &bblocks [bb->block_num];
4550 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4551 LLVMValueRef switch_ins = l->data;
4552 GSList *bb_list = info->call_handler_return_bbs;
4554 for (i = 0; i < g_slist_length (bb_list); ++i)
4555 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4559 if (cfg->verbose_level > 1)
4560 mono_llvm_dump_value (method);
4562 mark_as_used (module, method);
4564 if (cfg->compile_aot) {
4565 /* Don't generate native code, keep the LLVM IR */
4566 if (cfg->compile_aot && cfg->verbose_level)
4567 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4569 //LLVMVerifyFunction(method, 0);
4571 mono_llvm_optimize_method (method);
4573 if (cfg->verbose_level > 1)
4574 mono_llvm_dump_value (method);
4576 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4578 /* Set by emit_cb */
4579 g_assert (cfg->code_len);
4581 /* FIXME: Free the LLVM IL for the function */
4589 /* Need to add unused phi nodes as they can be referenced by other values */
4590 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4591 LLVMBuilderRef builder;
4593 builder = create_builder (ctx);
4594 LLVMPositionBuilderAtEnd (builder, phi_bb);
4596 for (i = 0; i < phi_values->len; ++i) {
4597 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4598 if (LLVMGetInstructionParent (v) == NULL)
4599 LLVMInsertIntoBuilder (builder, v);
4602 LLVMDeleteFunction (method);
4607 g_free (ctx->addresses);
4608 g_free (ctx->vreg_types);
4609 g_free (ctx->vreg_cli_types);
4610 g_free (ctx->pindexes);
4611 g_free (ctx->is_dead);
4612 g_free (ctx->unreachable);
4613 g_ptr_array_free (phi_values, TRUE);
4614 g_free (ctx->bblocks);
4615 g_hash_table_destroy (ctx->region_to_handler);
4616 g_free (method_name);
4617 g_ptr_array_free (bblock_list, TRUE);
4619 for (l = ctx->builders; l; l = l->next) {
4620 LLVMBuilderRef builder = l->data;
4621 LLVMDisposeBuilder (builder);
4626 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4628 mono_loader_unlock ();
4632 * mono_llvm_emit_call:
4634 * Same as mono_arch_emit_call () for LLVM.
4637 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4640 MonoMethodSignature *sig;
4641 int i, n, stack_size;
4646 sig = call->signature;
4647 n = sig->param_count + sig->hasthis;
4649 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4651 if (cfg->disable_llvm)
4654 if (sig->call_convention == MONO_CALL_VARARG) {
4655 cfg->exception_message = g_strdup ("varargs");
4656 cfg->disable_llvm = TRUE;
4659 for (i = 0; i < n; ++i) {
4662 ainfo = call->cinfo->args + i;
4664 in = call->args [i];
4666 /* Simply remember the arguments */
4667 switch (ainfo->storage) {
4669 MONO_INST_NEW (cfg, ins, OP_MOVE);
4670 ins->dreg = mono_alloc_ireg (cfg);
4671 ins->sreg1 = in->dreg;
4673 case LLVMArgInFPReg:
4674 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4675 ins->dreg = mono_alloc_freg (cfg);
4676 ins->sreg1 = in->dreg;
4678 case LLVMArgVtypeByVal:
4679 case LLVMArgVtypeInReg:
4680 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4681 ins->dreg = mono_alloc_ireg (cfg);
4682 ins->sreg1 = in->dreg;
4683 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4686 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4687 cfg->exception_message = g_strdup ("ainfo->storage");
4688 cfg->disable_llvm = TRUE;
4692 if (!cfg->disable_llvm) {
4693 MONO_ADD_INS (cfg->cbb, ins);
4694 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4699 static unsigned char*
4700 alloc_cb (LLVMValueRef function, int size)
4704 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4708 return mono_domain_code_reserve (cfg->domain, size);
4710 return mono_domain_code_reserve (mono_domain_get (), size);
4715 emitted_cb (LLVMValueRef function, void *start, void *end)
4719 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4721 cfg->code_len = (guint8*)end - (guint8*)start;
4725 exception_cb (void *data)
4728 MonoJitExceptionInfo *ei;
4729 guint32 ei_len, i, j, nested_len, nindex;
4730 gpointer *type_info;
4731 int this_reg, this_offset;
4733 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4737 * data points to a DWARF FDE structure, convert it to our unwind format and
4739 * An alternative would be to save it directly, and modify our unwinder to work
4742 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);
4744 /* Count nested clauses */
4746 for (i = 0; i < ei_len; ++i) {
4747 for (j = 0; j < ei_len; ++j) {
4748 gint32 cindex1 = *(gint32*)type_info [i];
4749 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4750 gint32 cindex2 = *(gint32*)type_info [j];
4751 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4753 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4759 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4760 cfg->llvm_ex_info_len = ei_len + nested_len;
4761 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4762 /* Fill the rest of the information from the type info */
4763 for (i = 0; i < ei_len; ++i) {
4764 gint32 clause_index = *(gint32*)type_info [i];
4765 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4767 cfg->llvm_ex_info [i].flags = clause->flags;
4768 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4772 * For nested clauses, the LLVM produced exception info associates the try interval with
4773 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4775 /* FIXME: These should be order with the normal clauses */
4777 for (i = 0; i < ei_len; ++i) {
4778 for (j = 0; j < ei_len; ++j) {
4779 gint32 cindex1 = *(gint32*)type_info [i];
4780 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4781 gint32 cindex2 = *(gint32*)type_info [j];
4782 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4784 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4786 * The try interval comes from the nested clause, everything else from the
4789 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4790 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4791 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4796 g_assert (nindex == ei_len + nested_len);
4797 cfg->llvm_this_reg = this_reg;
4798 cfg->llvm_this_offset = this_offset;
4800 /* type_info [i] is cfg mempool allocated, no need to free it */
4807 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4809 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4813 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4815 LLVMTypeRef param_types [4];
4817 param_types [0] = param_type1;
4818 param_types [1] = param_type2;
4820 AddFunc (module, name, ret_type, param_types, 2);
4824 add_intrinsics (LLVMModuleRef module)
4826 /* Emit declarations of instrinsics */
4828 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4829 * type doesn't seem to do any locking.
4832 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4834 memset_param_count = 5;
4835 memset_func_name = "llvm.memset.p0i8.i32";
4837 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4841 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4843 memcpy_param_count = 5;
4844 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4846 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4850 LLVMTypeRef params [] = { LLVMDoubleType () };
4852 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4853 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4854 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4856 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4857 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4861 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4862 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4864 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4865 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4866 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4867 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4868 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4869 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4873 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4874 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4876 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4877 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4878 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4879 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4880 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4881 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4885 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4886 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4887 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4889 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4891 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4896 LLVMTypeRef arg_types [2];
4897 LLVMTypeRef ret_type;
4899 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4900 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4901 ret_type = LLVMInt32Type ();
4903 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4905 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4908 /* SSE intrinsics */
4910 LLVMTypeRef ret_type, arg_types [2];
4913 ret_type = type_to_simd_type (MONO_TYPE_I4);
4914 arg_types [0] = ret_type;
4915 arg_types [1] = ret_type;
4916 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4917 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4918 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4920 ret_type = type_to_simd_type (MONO_TYPE_I2);
4921 arg_types [0] = ret_type;
4922 arg_types [1] = ret_type;
4923 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4924 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4925 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4926 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4927 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4928 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4930 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4931 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4932 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4933 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4935 ret_type = type_to_simd_type (MONO_TYPE_I1);
4936 arg_types [0] = ret_type;
4937 arg_types [1] = ret_type;
4938 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4939 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4940 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4941 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4942 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4943 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4944 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4945 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4946 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4948 ret_type = type_to_simd_type (MONO_TYPE_I8);
4949 arg_types [0] = ret_type;
4950 arg_types [1] = ret_type;
4951 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4953 ret_type = type_to_simd_type (MONO_TYPE_R8);
4954 arg_types [0] = ret_type;
4955 arg_types [1] = ret_type;
4956 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4957 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4958 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4959 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4960 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4962 ret_type = type_to_simd_type (MONO_TYPE_R4);
4963 arg_types [0] = ret_type;
4964 arg_types [1] = ret_type;
4965 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4966 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4967 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4968 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4969 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4972 ret_type = type_to_simd_type (MONO_TYPE_I1);
4973 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4974 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4975 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4976 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4977 ret_type = type_to_simd_type (MONO_TYPE_I2);
4978 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4979 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4980 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4981 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4984 ret_type = type_to_simd_type (MONO_TYPE_R8);
4985 arg_types [0] = ret_type;
4986 arg_types [1] = ret_type;
4987 arg_types [2] = LLVMInt8Type ();
4988 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4989 ret_type = type_to_simd_type (MONO_TYPE_R4);
4990 arg_types [0] = ret_type;
4991 arg_types [1] = ret_type;
4992 arg_types [2] = LLVMInt8Type ();
4993 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4995 /* Conversion ops */
4996 ret_type = type_to_simd_type (MONO_TYPE_R8);
4997 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4998 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4999 ret_type = type_to_simd_type (MONO_TYPE_R4);
5000 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5001 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5002 ret_type = type_to_simd_type (MONO_TYPE_I4);
5003 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5004 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5005 ret_type = type_to_simd_type (MONO_TYPE_I4);
5006 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5007 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5008 ret_type = type_to_simd_type (MONO_TYPE_R4);
5009 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5010 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5011 ret_type = type_to_simd_type (MONO_TYPE_R8);
5012 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5013 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5015 ret_type = type_to_simd_type (MONO_TYPE_I4);
5016 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5017 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5018 ret_type = type_to_simd_type (MONO_TYPE_I4);
5019 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5020 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5023 ret_type = type_to_simd_type (MONO_TYPE_R8);
5024 arg_types [0] = ret_type;
5025 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5026 ret_type = type_to_simd_type (MONO_TYPE_R4);
5027 arg_types [0] = ret_type;
5028 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5029 ret_type = type_to_simd_type (MONO_TYPE_R4);
5030 arg_types [0] = ret_type;
5031 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5032 ret_type = type_to_simd_type (MONO_TYPE_R4);
5033 arg_types [0] = ret_type;
5034 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5037 ret_type = type_to_simd_type (MONO_TYPE_I2);
5038 arg_types [0] = ret_type;
5039 arg_types [1] = LLVMInt32Type ();
5040 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5041 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5042 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5043 ret_type = type_to_simd_type (MONO_TYPE_I4);
5044 arg_types [0] = ret_type;
5045 arg_types [1] = LLVMInt32Type ();
5046 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5047 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5048 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5049 ret_type = type_to_simd_type (MONO_TYPE_I8);
5050 arg_types [0] = ret_type;
5051 arg_types [1] = LLVMInt32Type ();
5052 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5053 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5056 ret_type = LLVMInt32Type ();
5057 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5058 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5061 if (IS_LLVM_MONO_BRANCH) {
5062 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5065 /* Load/Store intrinsics */
5066 if (IS_LLVM_MONO_BRANCH) {
5067 LLVMTypeRef arg_types [5];
5071 for (i = 1; i <= 8; i *= 2) {
5072 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5073 arg_types [1] = LLVMInt32Type ();
5074 arg_types [2] = LLVMInt1Type ();
5075 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5076 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5078 arg_types [0] = LLVMIntType (i * 8);
5079 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5080 arg_types [2] = LLVMInt32Type ();
5081 arg_types [3] = LLVMInt1Type ();
5082 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5083 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5089 mono_llvm_init (void)
5091 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5095 init_jit_module (void)
5097 MonoJitICallInfo *info;
5099 if (jit_module_inited)
5102 mono_loader_lock ();
5104 if (jit_module_inited) {
5105 mono_loader_unlock ();
5109 jit_module.module = LLVMModuleCreateWithName ("mono");
5111 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5113 add_intrinsics (jit_module.module);
5115 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5117 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5119 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5121 jit_module_inited = TRUE;
5123 mono_loader_unlock ();
5127 mono_llvm_cleanup (void)
5130 mono_llvm_dispose_ee (ee);
5132 if (jit_module.llvm_types)
5133 g_hash_table_destroy (jit_module.llvm_types);
5135 if (aot_module.module)
5136 LLVMDisposeModule (aot_module.module);
5138 LLVMContextDispose (LLVMGetGlobalContext ());
5142 mono_llvm_create_aot_module (const char *got_symbol)
5144 /* Delete previous module */
5145 if (aot_module.plt_entries)
5146 g_hash_table_destroy (aot_module.plt_entries);
5147 if (aot_module.module)
5148 LLVMDisposeModule (aot_module.module);
5150 memset (&aot_module, 0, sizeof (aot_module));
5152 aot_module.module = LLVMModuleCreateWithName ("aot");
5153 aot_module.got_symbol = got_symbol;
5155 add_intrinsics (aot_module.module);
5159 * We couldn't compute the type of the LLVM global representing the got because
5160 * its size is only known after all the methods have been emitted. So create
5161 * a dummy variable, and replace all uses it with the real got variable when
5162 * its size is known in mono_llvm_emit_aot_module ().
5165 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5167 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5168 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5171 /* Add a dummy personality function */
5173 LLVMBasicBlockRef lbb;
5174 LLVMBuilderRef lbuilder;
5175 LLVMValueRef personality;
5177 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5178 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5179 lbb = LLVMAppendBasicBlock (personality, "BB0");
5180 lbuilder = LLVMCreateBuilder ();
5181 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5182 LLVMBuildRetVoid (lbuilder);
5185 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5186 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5190 * Emit the aot module into the LLVM bitcode file FILENAME.
5193 mono_llvm_emit_aot_module (const char *filename, int got_size)
5195 LLVMTypeRef got_type;
5196 LLVMValueRef real_got;
5199 * Create the real got variable and replace all uses of the dummy variable with
5202 got_type = LLVMArrayType (IntPtrType (), got_size);
5203 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5204 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5205 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5207 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5209 mark_as_used (aot_module.module, real_got);
5211 /* Delete the dummy got so it doesn't become a global */
5212 LLVMDeleteGlobal (aot_module.got_var);
5218 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5219 g_assert_not_reached ();
5224 LLVMWriteBitcodeToFile (aot_module.module, filename);
5229 - Emit LLVM IR from the mono IR using the LLVM C API.
5230 - The original arch specific code remains, so we can fall back to it if we run
5231 into something we can't handle.
5235 A partial list of issues:
5236 - Handling of opcodes which can throw exceptions.
5238 In the mono JIT, these are implemented using code like this:
5245 push throw_pos - method
5246 call <exception trampoline>
5248 The problematic part is push throw_pos - method, which cannot be represented
5249 in the LLVM IR, since it does not support label values.
5250 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5251 be implemented in JIT mode ?
5252 -> a possible but slower implementation would use the normal exception
5253 throwing code but it would need to control the placement of the throw code
5254 (it needs to be exactly after the compare+branch).
5255 -> perhaps add a PC offset intrinsics ?
5257 - efficient implementation of .ovf opcodes.
5259 These are currently implemented as:
5260 <ins which sets the condition codes>
5263 Some overflow opcodes are now supported by LLVM SVN.
5265 - exception handling, unwinding.
5266 - SSA is disabled for methods with exception handlers
5267 - How to obtain unwind info for LLVM compiled methods ?
5268 -> this is now solved by converting the unwind info generated by LLVM
5270 - LLVM uses the c++ exception handling framework, while we use our home grown
5271 code, and couldn't use the c++ one:
5272 - its not supported under VC++, other exotic platforms.
5273 - it might be impossible to support filter clauses with it.
5277 The trampolines need a predictable call sequence, since they need to disasm
5278 the calling code to obtain register numbers / offsets.
5280 LLVM currently generates this code in non-JIT mode:
5281 mov -0x98(%rax),%eax
5283 Here, the vtable pointer is lost.
5284 -> solution: use one vtable trampoline per class.
5286 - passing/receiving the IMT pointer/RGCTX.
5287 -> solution: pass them as normal arguments ?
5291 LLVM does not allow the specification of argument registers etc. This means
5292 that all calls are made according to the platform ABI.
5294 - passing/receiving vtypes.
5296 Vtypes passed/received in registers are handled by the front end by using
5297 a signature with scalar arguments, and loading the parts of the vtype into those
5300 Vtypes passed on the stack are handled using the 'byval' attribute.
5304 Supported though alloca, we need to emit the load/store code.
5308 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5309 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5310 This is made easier because the IR is already in SSA form.
5311 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5312 types are frequently used incorrectly.
5317 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5318 append the AOT data structures to that file. For methods which cannot be
5319 handled by LLVM, the normal JIT compiled versions are used.
5322 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5323 * - each bblock should end with a branch
5324 * - setting the return value, making cfg->ret non-volatile
5325 * - avoid some transformations in the JIT which make it harder for us to generate
5327 * - use pointer types to help optimizations.