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>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
33 LLVMValueRef throw, rethrow, throw_corlib_exception;
34 GHashTable *llvm_types;
36 const char *got_symbol;
37 GHashTable *plt_entries;
41 * Information associated by the backend with mono basic blocks.
44 LLVMBasicBlockRef bblock, end_bblock;
45 LLVMValueRef finally_ind;
46 gboolean added, invoke_target;
48 * If this bblock is the start of a finally clause, this is a list of bblocks it
49 * needs to branch to in ENDFINALLY.
51 GSList *call_handler_return_bbs;
53 * If this bblock is the start of a finally clause, this is the bblock that
54 * CALL_HANDLER needs to branch to.
56 LLVMBasicBlockRef call_handler_target_bb;
57 /* The list of switch statements generated by ENDFINALLY instructions */
58 GSList *endfinally_switch_ins_list;
63 * Structure containing emit state
68 /* Maps method names to the corresponding LLVMValueRef */
69 GHashTable *emitted_method_decls;
73 MonoLLVMModule *lmodule;
76 int sindex, default_index, ex_index;
77 LLVMBuilderRef builder;
78 LLVMValueRef *values, *addresses;
79 MonoType **vreg_cli_types;
81 MonoMethodSignature *sig;
83 GHashTable *region_to_handler;
84 LLVMBuilderRef alloca_builder;
85 LLVMValueRef last_alloca;
86 LLVMValueRef rgctx_arg;
87 LLVMTypeRef *vreg_types;
89 gboolean *unreachable;
98 MonoBasicBlock *in_bb;
103 * Instruction metadata
104 * This is the same as ins_info, but LREG != IREG.
112 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
113 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
120 /* keep in sync with the enum in mini.h */
123 #include "mini-ops.h"
128 #if SIZEOF_VOID_P == 4
129 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
131 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
134 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
137 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
139 #define TRACE_FAILURE(msg)
143 #define IS_TARGET_X86 1
145 #define IS_TARGET_X86 0
148 #define LLVM_FAILURE(ctx, reason) do { \
149 TRACE_FAILURE (reason); \
150 (ctx)->cfg->exception_message = g_strdup (reason); \
151 (ctx)->cfg->disable_llvm = TRUE; \
155 #define CHECK_FAILURE(ctx) do { \
156 if ((ctx)->cfg->disable_llvm) \
160 static LLVMIntPredicate cond_to_llvm_cond [] = {
173 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
186 static LLVMExecutionEngineRef ee;
187 static MonoNativeTlsKey current_cfg_tls_id;
189 static MonoLLVMModule jit_module, aot_module;
190 static gboolean jit_module_inited;
191 static int memset_param_count, memcpy_param_count;
192 static const char *memset_func_name;
193 static const char *memcpy_func_name;
195 static void init_jit_module (void);
200 * The LLVM type with width == sizeof (gpointer)
205 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
211 * Return the size of the LLVM representation of the vtype T.
214 get_vtype_size (MonoType *t)
218 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
220 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
227 * simd_class_to_llvm_type:
229 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
232 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
234 if (!strcmp (klass->name, "Vector2d")) {
235 return LLVMVectorType (LLVMDoubleType (), 2);
236 } else if (!strcmp (klass->name, "Vector2l")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector2ul")) {
239 return LLVMVectorType (LLVMInt64Type (), 2);
240 } else if (!strcmp (klass->name, "Vector4i")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4ui")) {
243 return LLVMVectorType (LLVMInt32Type (), 4);
244 } else if (!strcmp (klass->name, "Vector4f")) {
245 return LLVMVectorType (LLVMFloatType (), 4);
246 } else if (!strcmp (klass->name, "Vector8s")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector8us")) {
249 return LLVMVectorType (LLVMInt16Type (), 8);
250 } else if (!strcmp (klass->name, "Vector16sb")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else if (!strcmp (klass->name, "Vector16b")) {
253 return LLVMVectorType (LLVMInt8Type (), 16);
255 printf ("%s\n", klass->name);
261 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
262 static inline G_GNUC_UNUSED LLVMTypeRef
263 type_to_simd_type (int type)
267 return LLVMVectorType (LLVMInt8Type (), 16);
269 return LLVMVectorType (LLVMInt16Type (), 8);
271 return LLVMVectorType (LLVMInt32Type (), 4);
273 return LLVMVectorType (LLVMInt64Type (), 2);
275 return LLVMVectorType (LLVMDoubleType (), 2);
277 return LLVMVectorType (LLVMFloatType (), 4);
279 g_assert_not_reached ();
287 * Return the LLVM type corresponding to T.
290 type_to_llvm_type (EmitContext *ctx, MonoType *t)
293 return LLVMPointerType (LLVMInt8Type (), 0);
296 return LLVMVoidType ();
298 return LLVMInt8Type ();
300 return LLVMInt16Type ();
302 return LLVMInt32Type ();
304 return LLVMInt8Type ();
306 return LLVMInt16Type ();
308 return LLVMInt32Type ();
309 case MONO_TYPE_BOOLEAN:
310 return LLVMInt8Type ();
313 return LLVMInt64Type ();
315 return LLVMInt16Type ();
317 return LLVMFloatType ();
319 return LLVMDoubleType ();
322 return IntPtrType ();
323 case MONO_TYPE_OBJECT:
324 case MONO_TYPE_CLASS:
325 case MONO_TYPE_ARRAY:
326 case MONO_TYPE_SZARRAY:
327 case MONO_TYPE_STRING:
329 return IntPtrType ();
332 /* Because of generic sharing */
333 if (mini_type_var_is_vt (ctx->cfg, t))
334 return type_to_llvm_type (ctx, mini_get_gsharedvt_alloc_type_for_type (ctx->cfg, t));
336 return IntPtrType ();
337 case MONO_TYPE_GENERICINST:
338 if (!mono_type_generic_inst_is_valuetype (t))
339 return IntPtrType ();
341 case MONO_TYPE_VALUETYPE:
342 case MONO_TYPE_TYPEDBYREF: {
346 klass = mono_class_from_mono_type (t);
348 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
349 return simd_class_to_llvm_type (ctx, klass);
352 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
353 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
356 LLVMTypeRef *eltypes;
359 size = get_vtype_size (t);
361 eltypes = g_new (LLVMTypeRef, size);
362 for (i = 0; i < size; ++i)
363 eltypes [i] = LLVMInt8Type ();
365 name = mono_type_full_name (&klass->byval_arg);
366 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
367 LLVMStructSetBody (ltype, eltypes, size, FALSE);
368 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
375 printf ("X: %d\n", t->type);
376 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
377 ctx->cfg->disable_llvm = TRUE;
385 * Return whenever T is an unsigned int type.
388 type_is_unsigned (EmitContext *ctx, MonoType *t)
404 * type_to_llvm_arg_type:
406 * Same as type_to_llvm_type, but treat i8/i16 as i32.
409 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
411 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
413 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
415 * LLVM generates code which only sets the lower bits, while JITted
416 * code expects all the bits to be set.
418 ptype = LLVMInt32Type ();
425 * llvm_type_to_stack_type:
427 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
430 static G_GNUC_UNUSED LLVMTypeRef
431 llvm_type_to_stack_type (LLVMTypeRef type)
435 if (type == LLVMInt8Type ())
436 return LLVMInt32Type ();
437 else if (type == LLVMInt16Type ())
438 return LLVMInt32Type ();
439 else if (type == LLVMFloatType ())
440 return LLVMDoubleType ();
446 * regtype_to_llvm_type:
448 * Return the LLVM type corresponding to the regtype C used in instruction
452 regtype_to_llvm_type (char c)
456 return LLVMInt32Type ();
458 return LLVMInt64Type ();
460 return LLVMDoubleType ();
469 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
472 op_to_llvm_type (int opcode)
477 return LLVMInt8Type ();
480 return LLVMInt8Type ();
483 return LLVMInt16Type ();
486 return LLVMInt16Type ();
489 return LLVMInt32Type ();
492 return LLVMInt32Type ();
494 return LLVMInt64Type ();
496 return LLVMFloatType ();
498 return LLVMDoubleType ();
500 return LLVMInt64Type ();
502 return LLVMInt32Type ();
504 return LLVMInt64Type ();
507 return LLVMInt8Type ();
510 return LLVMInt16Type ();
513 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
520 return LLVMInt32Type ();
527 return LLVMInt64Type ();
529 printf ("%s\n", mono_inst_name (opcode));
530 g_assert_not_reached ();
536 * load_store_to_llvm_type:
538 * Return the size/sign/zero extension corresponding to the load/store opcode
542 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
548 case OP_LOADI1_MEMBASE:
549 case OP_STOREI1_MEMBASE_REG:
550 case OP_STOREI1_MEMBASE_IMM:
553 return LLVMInt8Type ();
554 case OP_LOADU1_MEMBASE:
558 return LLVMInt8Type ();
559 case OP_LOADI2_MEMBASE:
560 case OP_STOREI2_MEMBASE_REG:
561 case OP_STOREI2_MEMBASE_IMM:
564 return LLVMInt16Type ();
565 case OP_LOADU2_MEMBASE:
569 return LLVMInt16Type ();
570 case OP_LOADI4_MEMBASE:
571 case OP_LOADU4_MEMBASE:
574 case OP_STOREI4_MEMBASE_REG:
575 case OP_STOREI4_MEMBASE_IMM:
577 return LLVMInt32Type ();
578 case OP_LOADI8_MEMBASE:
580 case OP_STOREI8_MEMBASE_REG:
581 case OP_STOREI8_MEMBASE_IMM:
583 return LLVMInt64Type ();
584 case OP_LOADR4_MEMBASE:
585 case OP_STORER4_MEMBASE_REG:
587 return LLVMFloatType ();
588 case OP_LOADR8_MEMBASE:
589 case OP_STORER8_MEMBASE_REG:
591 return LLVMDoubleType ();
592 case OP_LOAD_MEMBASE:
594 case OP_STORE_MEMBASE_REG:
595 case OP_STORE_MEMBASE_IMM:
596 *size = sizeof (gpointer);
597 return IntPtrType ();
599 g_assert_not_reached ();
607 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
610 ovf_op_to_intrins (int opcode)
614 return "llvm.sadd.with.overflow.i32";
616 return "llvm.uadd.with.overflow.i32";
618 return "llvm.ssub.with.overflow.i32";
620 return "llvm.usub.with.overflow.i32";
622 return "llvm.smul.with.overflow.i32";
624 return "llvm.umul.with.overflow.i32";
626 return "llvm.sadd.with.overflow.i64";
628 return "llvm.uadd.with.overflow.i64";
630 return "llvm.ssub.with.overflow.i64";
632 return "llvm.usub.with.overflow.i64";
634 return "llvm.smul.with.overflow.i64";
636 return "llvm.umul.with.overflow.i64";
638 g_assert_not_reached ();
644 simd_op_to_intrins (int opcode)
647 #if defined(TARGET_X86) || defined(TARGET_AMD64)
649 return "llvm.x86.sse2.min.pd";
651 return "llvm.x86.sse.min.ps";
653 return "llvm.x86.sse41.pminud";
655 return "llvm.x86.sse41.pminuw";
657 return "llvm.x86.sse2.pminu.b";
659 return "llvm.x86.sse2.pmins.w";
661 return "llvm.x86.sse2.max.pd";
663 return "llvm.x86.sse.max.ps";
665 return "llvm.x86.sse3.hadd.pd";
667 return "llvm.x86.sse3.hadd.ps";
669 return "llvm.x86.sse3.hsub.pd";
671 return "llvm.x86.sse3.hsub.ps";
673 return "llvm.x86.sse41.pmaxud";
675 return "llvm.x86.sse41.pmaxuw";
677 return "llvm.x86.sse2.pmaxu.b";
679 return "llvm.x86.sse3.addsub.ps";
681 return "llvm.x86.sse3.addsub.pd";
682 case OP_EXTRACT_MASK:
683 return "llvm.x86.sse2.pmovmskb.128";
686 return "llvm.x86.sse2.psrli.w";
689 return "llvm.x86.sse2.psrli.d";
692 return "llvm.x86.sse2.psrli.q";
695 return "llvm.x86.sse2.pslli.w";
698 return "llvm.x86.sse2.pslli.d";
701 return "llvm.x86.sse2.pslli.q";
704 return "llvm.x86.sse2.psrai.w";
707 return "llvm.x86.sse2.psrai.d";
709 return "llvm.x86.sse2.padds.b";
711 return "llvm.x86.sse2.padds.w";
713 return "llvm.x86.sse2.psubs.b";
715 return "llvm.x86.sse2.psubs.w";
716 case OP_PADDB_SAT_UN:
717 return "llvm.x86.sse2.paddus.b";
718 case OP_PADDW_SAT_UN:
719 return "llvm.x86.sse2.paddus.w";
720 case OP_PSUBB_SAT_UN:
721 return "llvm.x86.sse2.psubus.b";
722 case OP_PSUBW_SAT_UN:
723 return "llvm.x86.sse2.psubus.w";
725 return "llvm.x86.sse2.pavg.b";
727 return "llvm.x86.sse2.pavg.w";
729 return "llvm.x86.sse.sqrt.ps";
731 return "llvm.x86.sse2.sqrt.pd";
733 return "llvm.x86.sse.rsqrt.ps";
735 return "llvm.x86.sse.rcp.ps";
737 return "llvm.x86.sse2.cvtdq2pd";
739 return "llvm.x86.sse2.cvtdq2ps";
741 return "llvm.x86.sse2.cvtpd2dq";
743 return "llvm.x86.sse2.cvtps2dq";
745 return "llvm.x86.sse2.cvtpd2ps";
747 return "llvm.x86.sse2.cvtps2pd";
749 return "llvm.x86.sse2.cvttpd2dq";
751 return "llvm.x86.sse2.cvttps2dq";
753 return "llvm.x86.sse.cmp.ps";
755 return "llvm.x86.sse2.cmp.pd";
757 return "llvm.x86.sse2.packsswb.128";
759 return "llvm.x86.sse2.packssdw.128";
761 return "llvm.x86.sse2.packuswb.128";
763 return "llvm.x86.sse41.packusdw";
765 return "llvm.x86.sse2.pmulh.w";
766 case OP_PMULW_HIGH_UN:
767 return "llvm.x86.sse2.pmulhu.w";
770 g_assert_not_reached ();
776 simd_op_to_llvm_type (int opcode)
778 #if defined(TARGET_X86) || defined(TARGET_AMD64)
782 return type_to_simd_type (MONO_TYPE_R8);
785 return type_to_simd_type (MONO_TYPE_I8);
788 return type_to_simd_type (MONO_TYPE_I4);
793 return type_to_simd_type (MONO_TYPE_I2);
797 return type_to_simd_type (MONO_TYPE_I1);
799 return type_to_simd_type (MONO_TYPE_R4);
802 return type_to_simd_type (MONO_TYPE_I4);
806 return type_to_simd_type (MONO_TYPE_R8);
810 return type_to_simd_type (MONO_TYPE_R4);
811 case OP_EXTRACT_MASK:
812 return type_to_simd_type (MONO_TYPE_I1);
818 return type_to_simd_type (MONO_TYPE_R4);
821 return type_to_simd_type (MONO_TYPE_R8);
823 g_assert_not_reached ();
834 * Return the LLVM basic block corresponding to BB.
836 static LLVMBasicBlockRef
837 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
841 if (ctx->bblocks [bb->block_num].bblock == NULL) {
842 if (bb->flags & BB_EXCEPTION_HANDLER) {
843 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
844 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
846 sprintf (bb_name, "BB%d", bb->block_num);
849 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
850 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
853 return ctx->bblocks [bb->block_num].bblock;
859 * Return the last LLVM bblock corresponding to BB.
860 * This might not be equal to the bb returned by get_bb () since we need to generate
861 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
863 static LLVMBasicBlockRef
864 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
867 return ctx->bblocks [bb->block_num].end_bblock;
870 static LLVMBasicBlockRef
871 gen_bb (EmitContext *ctx, const char *prefix)
875 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
876 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
882 * Return the target of the patch identified by TYPE and TARGET.
885 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
889 memset (&ji, 0, sizeof (ji));
891 ji.data.target = target;
893 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
899 * Emit code to convert the LLVM value V to DTYPE.
902 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
904 LLVMTypeRef stype = LLVMTypeOf (v);
906 if (stype != dtype) {
907 gboolean ext = FALSE;
910 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
912 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
914 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
918 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
920 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
921 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
924 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
925 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
926 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
927 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
928 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
929 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
930 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
931 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
933 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
934 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
935 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
936 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
937 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
938 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
940 #ifdef MONO_ARCH_SOFT_FLOAT
941 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
942 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
943 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
944 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
947 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
948 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
951 LLVMDumpValue (LLVMConstNull (dtype));
952 g_assert_not_reached ();
960 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
962 return convert_full (ctx, v, dtype, FALSE);
966 * emit_volatile_load:
968 * If vreg is volatile, emit a load from its address.
971 emit_volatile_load (EmitContext *ctx, int vreg)
975 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
976 t = ctx->vreg_cli_types [vreg];
977 if (t && !t->byref) {
979 * Might have to zero extend since llvm doesn't have
982 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
983 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
984 else if (t->type == MONO_TYPE_U8)
985 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
992 * emit_volatile_store:
994 * If VREG is volatile, emit a store from its value to its address.
997 emit_volatile_store (EmitContext *ctx, int vreg)
999 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1001 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1002 g_assert (ctx->addresses [vreg]);
1003 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1009 * Maps parameter indexes in the original signature to parameter indexes
1010 * in the LLVM signature.
1013 /* The indexes of various special arguments in the LLVM signature */
1014 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1018 * sig_to_llvm_sig_full:
1020 * Return the LLVM signature corresponding to the mono signature SIG using the
1021 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1024 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1027 LLVMTypeRef ret_type;
1028 LLVMTypeRef *param_types = NULL;
1030 int i, j, pindex, vret_arg_pindex = 0;
1032 gboolean vretaddr = FALSE;
1035 memset (sinfo, 0, sizeof (LLVMSigInfo));
1037 ret_type = type_to_llvm_type (ctx, sig->ret);
1038 CHECK_FAILURE (ctx);
1040 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1041 /* LLVM models this by returning an aggregate value */
1042 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1043 LLVMTypeRef members [2];
1045 members [0] = IntPtrType ();
1046 ret_type = LLVMStructType (members, 1, FALSE);
1048 g_assert_not_reached ();
1050 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1051 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1053 ret_type = LLVMVoidType ();
1056 pindexes = g_new0 (int, sig->param_count);
1057 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1059 if (cinfo && cinfo->rgctx_arg) {
1061 sinfo->rgctx_arg_pindex = pindex;
1062 param_types [pindex] = IntPtrType ();
1065 if (cinfo && cinfo->imt_arg) {
1067 sinfo->imt_arg_pindex = pindex;
1068 param_types [pindex] = IntPtrType ();
1072 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1073 vret_arg_pindex = pindex;
1074 if (cinfo->vret_arg_index == 1) {
1075 /* Add the slots consumed by the first argument */
1076 LLVMArgInfo *ainfo = &cinfo->args [0];
1077 switch (ainfo->storage) {
1078 case LLVMArgVtypeInReg:
1079 for (j = 0; j < 2; ++j) {
1080 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1090 sinfo->vret_arg_pindex = vret_arg_pindex;
1093 if (vretaddr && vret_arg_pindex == pindex)
1094 param_types [pindex ++] = IntPtrType ();
1097 sinfo->this_arg_pindex = pindex;
1098 param_types [pindex ++] = IntPtrType ();
1100 if (vretaddr && vret_arg_pindex == pindex)
1101 param_types [pindex ++] = IntPtrType ();
1102 for (i = 0; i < sig->param_count; ++i) {
1103 if (vretaddr && vret_arg_pindex == pindex)
1104 param_types [pindex ++] = IntPtrType ();
1105 pindexes [i] = pindex;
1106 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1107 for (j = 0; j < 2; ++j) {
1108 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1110 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1115 g_assert_not_reached ();
1118 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1119 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1120 CHECK_FAILURE (ctx);
1121 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1124 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1127 if (vretaddr && vret_arg_pindex == pindex)
1128 param_types [pindex ++] = IntPtrType ();
1130 CHECK_FAILURE (ctx);
1132 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1133 g_free (param_types);
1136 sinfo->pindexes = pindexes;
1144 g_free (param_types);
1150 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1152 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1156 * LLVMFunctionType1:
1158 * Create an LLVM function type from the arguments.
1160 static G_GNUC_UNUSED LLVMTypeRef
1161 LLVMFunctionType1(LLVMTypeRef ReturnType,
1162 LLVMTypeRef ParamType1,
1165 LLVMTypeRef param_types [1];
1167 param_types [0] = ParamType1;
1169 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1173 * LLVMFunctionType2:
1175 * Create an LLVM function type from the arguments.
1177 static G_GNUC_UNUSED LLVMTypeRef
1178 LLVMFunctionType2(LLVMTypeRef ReturnType,
1179 LLVMTypeRef ParamType1,
1180 LLVMTypeRef ParamType2,
1183 LLVMTypeRef param_types [2];
1185 param_types [0] = ParamType1;
1186 param_types [1] = ParamType2;
1188 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1192 * LLVMFunctionType3:
1194 * Create an LLVM function type from the arguments.
1196 static G_GNUC_UNUSED LLVMTypeRef
1197 LLVMFunctionType3(LLVMTypeRef ReturnType,
1198 LLVMTypeRef ParamType1,
1199 LLVMTypeRef ParamType2,
1200 LLVMTypeRef ParamType3,
1203 LLVMTypeRef param_types [3];
1205 param_types [0] = ParamType1;
1206 param_types [1] = ParamType2;
1207 param_types [2] = ParamType3;
1209 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1215 * Create an LLVM builder and remember it so it can be freed later.
1217 static LLVMBuilderRef
1218 create_builder (EmitContext *ctx)
1220 LLVMBuilderRef builder = LLVMCreateBuilder ();
1222 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1228 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1230 char *callee_name = mono_aot_get_plt_symbol (type, data);
1231 LLVMValueRef callee;
1236 if (ctx->cfg->compile_aot)
1237 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1238 mono_add_patch_info (ctx->cfg, 0, type, data);
1241 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1243 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1245 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1247 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1254 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1256 MonoMethodHeader *header = cfg->header;
1257 MonoExceptionClause *clause;
1261 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1262 return (bb->region >> 8) - 1;
1265 for (i = 0; i < header->num_clauses; ++i) {
1266 clause = &header->clauses [i];
1268 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1276 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1278 LLVMValueRef md_arg;
1281 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1282 md_arg = LLVMMDString ("mono", 4);
1283 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1289 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1293 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1295 MonoCompile *cfg = ctx->cfg;
1297 LLVMBuilderRef builder = *builder_ref;
1300 clause_index = get_handler_clause (cfg, bb);
1302 if (clause_index != -1) {
1303 MonoMethodHeader *header = cfg->header;
1304 MonoExceptionClause *ec = &header->clauses [clause_index];
1305 MonoBasicBlock *tblock;
1306 LLVMBasicBlockRef ex_bb, noex_bb;
1309 * Have to use an invoke instead of a call, branching to the
1310 * handler bblock of the clause containing this bblock.
1313 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1315 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1318 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1320 ex_bb = get_bb (ctx, tblock);
1322 noex_bb = gen_bb (ctx, "NOEX_BB");
1325 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1327 builder = ctx->builder = create_builder (ctx);
1328 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1330 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1332 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1333 ctx->builder = builder;
1336 *builder_ref = ctx->builder;
1342 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1344 const char *intrins_name;
1345 LLVMValueRef args [16], res;
1346 LLVMTypeRef addr_type;
1348 if (is_faulting && bb->region != -1) {
1350 * We handle loads which can fault by calling a mono specific intrinsic
1351 * using an invoke, so they are handled properly inside try blocks.
1352 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1353 * are marked with IntrReadArgMem.
1357 intrins_name = "llvm.mono.load.i8.p0i8";
1360 intrins_name = "llvm.mono.load.i16.p0i16";
1363 intrins_name = "llvm.mono.load.i32.p0i32";
1366 intrins_name = "llvm.mono.load.i64.p0i64";
1369 g_assert_not_reached ();
1372 addr_type = LLVMTypeOf (addr);
1373 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1374 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1377 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1378 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1379 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1381 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1382 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1383 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1384 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1391 * We emit volatile loads for loads which can fault, because otherwise
1392 * LLVM will generate invalid code when encountering a load from a
1395 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1397 /* Mark it with a custom metadata */
1400 set_metadata_flag (res, "mono.faulting.load");
1408 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1410 const char *intrins_name;
1411 LLVMValueRef args [16];
1413 if (is_faulting && bb->region != -1) {
1416 intrins_name = "llvm.mono.store.i8.p0i8";
1419 intrins_name = "llvm.mono.store.i16.p0i16";
1422 intrins_name = "llvm.mono.store.i32.p0i32";
1425 intrins_name = "llvm.mono.store.i64.p0i64";
1428 g_assert_not_reached ();
1431 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1432 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1433 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1438 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1439 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1440 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1442 LLVMBuildStore (*builder_ref, value, addr);
1447 * emit_cond_system_exception:
1449 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1450 * Might set the ctx exception.
1453 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1455 LLVMBasicBlockRef ex_bb, noex_bb;
1456 LLVMBuilderRef builder;
1457 MonoClass *exc_class;
1458 LLVMValueRef args [2];
1460 ex_bb = gen_bb (ctx, "EX_BB");
1461 noex_bb = gen_bb (ctx, "NOEX_BB");
1463 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1465 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1466 g_assert (exc_class);
1468 /* Emit exception throwing code */
1469 builder = create_builder (ctx);
1470 LLVMPositionBuilderAtEnd (builder, ex_bb);
1472 if (!ctx->lmodule->throw_corlib_exception) {
1473 LLVMValueRef callee;
1475 const char *icall_name;
1477 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1478 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1479 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1480 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1481 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1482 sig = sig_to_llvm_sig (ctx, throw_sig);
1484 if (ctx->cfg->compile_aot) {
1485 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1487 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1490 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1491 * - On x86, LLVM generated code doesn't push the arguments
1492 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1493 * arguments, not a pc offset.
1495 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1498 mono_memory_barrier ();
1499 ctx->lmodule->throw_corlib_exception = callee;
1503 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1505 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1508 * The LLVM mono branch contains changes so a block address can be passed as an
1509 * argument to a call.
1511 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1512 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1514 LLVMBuildUnreachable (builder);
1516 ctx->builder = create_builder (ctx);
1517 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1519 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1526 * emit_reg_to_vtype:
1528 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1531 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1535 size = get_vtype_size (t);
1537 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1538 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1541 for (j = 0; j < 2; ++j) {
1542 LLVMValueRef index [2], addr;
1543 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1544 LLVMTypeRef part_type;
1546 if (ainfo->pair_storage [j] == LLVMArgNone)
1549 part_type = LLVMIntType (part_size * 8);
1550 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1551 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1552 addr = LLVMBuildGEP (builder, address, index, 1, "");
1554 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1555 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1556 addr = LLVMBuildGEP (builder, address, index, 2, "");
1558 switch (ainfo->pair_storage [j]) {
1560 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1565 g_assert_not_reached ();
1568 size -= sizeof (gpointer);
1573 * emit_vtype_to_reg:
1575 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1576 * into REGS, and the number of registers into NREGS.
1579 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1584 size = get_vtype_size (t);
1586 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1587 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1590 for (j = 0; j < 2; ++j) {
1591 LLVMValueRef index [2], addr;
1592 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1594 if (ainfo->pair_storage [j] == LLVMArgNone)
1597 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1598 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1599 addr = LLVMBuildGEP (builder, address, index, 1, "");
1601 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1602 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1603 addr = LLVMBuildGEP (builder, address, index, 2, "");
1605 switch (ainfo->pair_storage [j]) {
1607 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1612 g_assert_not_reached ();
1614 size -= sizeof (gpointer);
1621 build_alloca (EmitContext *ctx, MonoType *t)
1623 MonoClass *k = mono_class_from_mono_type (t);
1626 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1629 align = mono_class_min_align (k);
1631 /* Sometimes align is not a power of 2 */
1632 while (mono_is_power_of_two (align) == -1)
1636 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1637 * get executed every time control reaches them.
1639 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1641 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1642 return ctx->last_alloca;
1646 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1649 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1651 LLVMTypeRef used_type;
1652 LLVMValueRef used, used_elem;
1654 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1655 used = LLVMAddGlobal (module, used_type, "llvm.used");
1656 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1657 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1658 LLVMSetLinkage (used, LLVMAppendingLinkage);
1659 LLVMSetSection (used, "llvm.metadata");
1665 * Emit code to load/convert arguments.
1668 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1671 MonoCompile *cfg = ctx->cfg;
1672 MonoMethodSignature *sig = ctx->sig;
1673 LLVMCallInfo *linfo = ctx->linfo;
1676 ctx->alloca_builder = create_builder (ctx);
1679 * Handle indirect/volatile variables by allocating memory for them
1680 * using 'alloca', and storing their address in a temporary.
1682 for (i = 0; i < cfg->num_varinfo; ++i) {
1683 MonoInst *var = cfg->varinfo [i];
1686 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1687 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1688 CHECK_FAILURE (ctx);
1689 /* Could be already created by an OP_VPHI */
1690 if (!ctx->addresses [var->dreg])
1691 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1692 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1696 for (i = 0; i < sig->param_count; ++i) {
1697 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1698 int reg = cfg->args [i + sig->hasthis]->dreg;
1700 if (ainfo->storage == LLVMArgVtypeInReg) {
1701 LLVMValueRef regs [2];
1704 * Emit code to save the argument from the registers to
1705 * the real argument.
1707 pindex = ctx->pindexes [i];
1708 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1709 if (ainfo->pair_storage [1] != LLVMArgNone)
1710 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1714 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1716 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1718 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1719 /* Treat these as normal values */
1720 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1722 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1723 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1725 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1726 /* Treat these as normal values */
1727 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1730 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1735 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1737 emit_volatile_store (ctx, cfg->args [0]->dreg);
1738 for (i = 0; i < sig->param_count; ++i)
1739 if (!mini_type_is_vtype (cfg, sig->params [i]))
1740 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1742 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1743 LLVMValueRef this_alloc;
1746 * The exception handling code needs the location where the this argument was
1747 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1748 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1749 * location into the LSDA.
1751 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1752 /* This volatile store will keep the alloca alive */
1753 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1755 set_metadata_flag (this_alloc, "mono.this");
1758 if (cfg->rgctx_var) {
1759 LLVMValueRef rgctx_alloc, store;
1762 * We handle the rgctx arg similarly to the this pointer.
1764 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1765 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1766 /* This volatile store will keep the alloca alive */
1767 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1769 set_metadata_flag (rgctx_alloc, "mono.this");
1773 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1774 * it needs to continue normally, or return back to the exception handling system.
1776 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1777 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1778 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1779 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1783 sprintf (name, "finally_ind_bb%d", bb->block_num);
1784 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1785 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1787 ctx->bblocks [bb->block_num].finally_ind = val;
1790 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1791 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1792 * LLVM optimizer passes.
1794 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1795 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1803 /* Have to export this for AOT */
1805 mono_personality (void);
1808 mono_personality (void)
1811 g_assert_not_reached ();
1815 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1817 MonoCompile *cfg = ctx->cfg;
1818 LLVMModuleRef module = ctx->module;
1819 LLVMValueRef *values = ctx->values;
1820 LLVMValueRef *addresses = ctx->addresses;
1821 MonoCallInst *call = (MonoCallInst*)ins;
1822 MonoMethodSignature *sig = call->signature;
1823 LLVMValueRef callee = NULL, lcall;
1825 LLVMCallInfo *cinfo;
1829 LLVMTypeRef llvm_sig;
1831 gboolean virtual, calli;
1832 LLVMBuilderRef builder = *builder_ref;
1835 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1836 LLVM_FAILURE (ctx, "non-default callconv");
1838 cinfo = call->cinfo;
1839 if (call->rgctx_arg_reg)
1840 cinfo->rgctx_arg = TRUE;
1841 if (call->imt_arg_reg)
1842 cinfo->imt_arg = TRUE;
1844 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1846 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1847 CHECK_FAILURE (ctx);
1849 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);
1850 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);
1852 /* FIXME: Avoid creating duplicate methods */
1854 if (ins->flags & MONO_INST_HAS_METHOD) {
1858 if (cfg->compile_aot) {
1859 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1861 LLVM_FAILURE (ctx, "can't encode patch");
1863 callee = LLVMAddFunction (module, "", llvm_sig);
1866 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1868 LLVMAddGlobalMapping (ee, callee, target);
1873 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1879 memset (&ji, 0, sizeof (ji));
1880 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1881 ji.data.target = info->name;
1883 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1885 if (cfg->compile_aot) {
1886 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1888 LLVM_FAILURE (ctx, "can't encode patch");
1890 callee = LLVMAddFunction (module, "", llvm_sig);
1891 target = (gpointer)mono_icall_get_wrapper (info);
1892 LLVMAddGlobalMapping (ee, callee, target);
1895 if (cfg->compile_aot) {
1897 if (cfg->abs_patches) {
1898 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1900 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1902 LLVM_FAILURE (ctx, "can't encode patch");
1906 LLVM_FAILURE (ctx, "aot");
1908 callee = LLVMAddFunction (module, "", llvm_sig);
1910 if (cfg->abs_patches) {
1911 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1914 * FIXME: Some trampolines might have
1915 * their own calling convention on some platforms.
1917 #ifndef TARGET_AMD64
1918 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)
1919 LLVM_FAILURE (ctx, "trampoline with own cconv");
1921 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1922 LLVMAddGlobalMapping (ee, callee, target);
1926 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1932 int size = sizeof (gpointer);
1935 g_assert (ins->inst_offset % size == 0);
1936 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1938 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1940 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1942 if (ins->flags & MONO_INST_HAS_METHOD) {
1947 * Collect and convert arguments
1949 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
1950 len = sizeof (LLVMValueRef) * nargs;
1951 args = alloca (len);
1952 memset (args, 0, len);
1953 l = call->out_ireg_args;
1955 if (call->rgctx_arg_reg) {
1956 g_assert (values [call->rgctx_arg_reg]);
1957 g_assert (sinfo.rgctx_arg_pindex < nargs);
1958 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1960 if (call->imt_arg_reg) {
1961 g_assert (values [call->imt_arg_reg]);
1962 g_assert (sinfo.imt_arg_pindex < nargs);
1963 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1967 if (!addresses [call->inst.dreg])
1968 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1969 g_assert (sinfo.vret_arg_pindex < nargs);
1970 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1973 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1976 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1980 pindex = sinfo.this_arg_pindex;
1982 pindex = sinfo.pindexes [i - 1];
1984 pindex = sinfo.pindexes [i];
1987 regpair = (guint32)(gssize)(l->data);
1988 reg = regpair & 0xffffff;
1989 args [pindex] = values [reg];
1990 if (ainfo->storage == LLVMArgVtypeInReg) {
1992 LLVMValueRef regs [2];
1997 g_assert (addresses [reg]);
1999 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2000 for (j = 0; j < nregs; ++j)
2001 args [pindex ++] = regs [j];
2004 // FIXME: Get rid of the VMOVE
2005 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2006 g_assert (addresses [reg]);
2007 args [pindex] = addresses [reg];
2009 g_assert (args [pindex]);
2010 if (i == 0 && sig->hasthis)
2011 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2013 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2019 // FIXME: Align call sites
2025 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2027 #ifdef LLVM_MONO_BRANCH
2029 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2031 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2032 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2034 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2035 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2037 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2039 if (call->rgctx_arg_reg)
2040 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2041 if (call->imt_arg_reg)
2042 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2045 /* Add byval attributes if needed */
2046 for (i = 0; i < sig->param_count; ++i) {
2047 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2049 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2050 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2055 * Convert the result
2057 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2058 LLVMValueRef regs [2];
2060 if (!addresses [ins->dreg])
2061 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2063 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2064 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2065 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2067 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2068 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2069 /* If the method returns an unsigned value, need to zext it */
2071 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));
2074 *builder_ref = ctx->builder;
2076 g_free (sinfo.pindexes);
2084 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2086 MonoCompile *cfg = ctx->cfg;
2087 MonoMethodSignature *sig = ctx->sig;
2088 LLVMValueRef method = ctx->lmethod;
2089 LLVMValueRef *values = ctx->values;
2090 LLVMValueRef *addresses = ctx->addresses;
2092 LLVMCallInfo *linfo = ctx->linfo;
2093 LLVMModuleRef module = ctx->module;
2094 BBInfo *bblocks = ctx->bblocks;
2096 LLVMBasicBlockRef cbb;
2097 LLVMBuilderRef builder, starting_builder;
2098 gboolean has_terminator;
2100 LLVMValueRef lhs, rhs;
2103 cbb = get_bb (ctx, bb);
2104 builder = create_builder (ctx);
2105 ctx->builder = builder;
2106 LLVMPositionBuilderAtEnd (builder, cbb);
2108 if (bb == cfg->bb_entry)
2109 emit_entry_bb (ctx, builder);
2110 CHECK_FAILURE (ctx);
2112 if (bb->flags & BB_EXCEPTION_HANDLER) {
2114 LLVMValueRef personality;
2115 LLVMBasicBlockRef target_bb;
2117 static gint32 mapping_inited;
2118 static int ti_generator;
2121 LLVMValueRef type_info;
2124 if (!bblocks [bb->block_num].invoke_target) {
2126 * LLVM asserts if llvm.eh.selector is called from a bblock which
2127 * doesn't have an invoke pointing at it.
2128 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2130 LLVM_FAILURE (ctx, "handler without invokes");
2133 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2135 if (cfg->compile_aot) {
2136 /* Use a dummy personality function */
2137 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2138 g_assert (personality);
2140 personality = LLVMGetNamedFunction (module, "mono_personality");
2141 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2142 LLVMAddGlobalMapping (ee, personality, mono_personality);
2145 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2147 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2150 * Create the type info
2152 sprintf (ti_name, "type_info_%d", ti_generator);
2155 if (cfg->compile_aot) {
2156 /* decode_eh_frame () in aot-runtime.c will decode this */
2157 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2158 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2161 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2163 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2166 * Enabling this causes llc to crash:
2167 * http://llvm.org/bugs/show_bug.cgi?id=6102
2169 //LLVM_FAILURE (ctx, "aot+clauses");
2171 // test_0_invalid_unbox_arrays () fails
2172 LLVM_FAILURE (ctx, "aot+clauses");
2176 * After the cfg mempool is freed, the type info will point to stale memory,
2177 * but this is not a problem, since we decode it once in exception_cb during
2180 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2181 *(gint32*)ti = clause_index;
2183 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2185 LLVMAddGlobalMapping (ee, type_info, ti);
2189 LLVMTypeRef members [2], ret_type;
2190 LLVMValueRef landing_pad;
2192 members [0] = i8ptr;
2193 members [1] = LLVMInt32Type ();
2194 ret_type = LLVMStructType (members, 2, FALSE);
2196 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2197 LLVMAddClause (landing_pad, type_info);
2199 /* Store the exception into the exvar */
2200 if (bb->in_scount == 1) {
2201 g_assert (bb->in_scount == 1);
2202 exvar = bb->in_stack [0];
2204 // FIXME: This is shared with filter clauses ?
2205 g_assert (!values [exvar->dreg]);
2207 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2208 emit_volatile_store (ctx, exvar->dreg);
2212 /* Start a new bblock which CALL_HANDLER can branch to */
2213 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2215 LLVMBuildBr (builder, target_bb);
2217 ctx->builder = builder = create_builder (ctx);
2218 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2220 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2224 has_terminator = FALSE;
2225 starting_builder = builder;
2226 for (ins = bb->code; ins; ins = ins->next) {
2227 const char *spec = LLVM_INS_INFO (ins->opcode);
2229 char dname_buf [128];
2232 if (nins > 5000 && builder == starting_builder) {
2233 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2234 LLVM_FAILURE (ctx, "basic block too long");
2238 /* There could be instructions after a terminator, skip them */
2241 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2242 sprintf (dname_buf, "t%d", ins->dreg);
2246 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2247 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2249 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2250 lhs = emit_volatile_load (ctx, ins->sreg1);
2252 /* It is ok for SETRET to have an uninitialized argument */
2253 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2254 LLVM_FAILURE (ctx, "sreg1");
2255 lhs = values [ins->sreg1];
2261 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2262 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2263 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2264 rhs = emit_volatile_load (ctx, ins->sreg2);
2266 if (!values [ins->sreg2])
2267 LLVM_FAILURE (ctx, "sreg2");
2268 rhs = values [ins->sreg2];
2274 //mono_print_ins (ins);
2275 switch (ins->opcode) {
2278 case OP_LIVERANGE_START:
2279 case OP_LIVERANGE_END:
2282 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2285 #if SIZEOF_VOID_P == 4
2286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2288 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2292 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2295 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2298 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2299 has_terminator = TRUE;
2305 LLVMBasicBlockRef new_bb;
2306 LLVMBuilderRef new_builder;
2308 // The default branch is already handled
2309 // FIXME: Handle it here
2311 /* Start new bblock */
2312 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2313 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2315 lhs = convert (ctx, lhs, LLVMInt32Type ());
2316 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2317 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2318 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2320 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2323 new_builder = create_builder (ctx);
2324 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2325 LLVMBuildUnreachable (new_builder);
2327 has_terminator = TRUE;
2328 g_assert (!ins->next);
2334 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2335 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2336 LLVMValueRef part1, retval;
2339 size = get_vtype_size (sig->ret);
2341 g_assert (addresses [ins->sreg1]);
2343 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2344 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2346 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2348 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2350 LLVMBuildRet (builder, retval);
2354 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2355 LLVMBuildRetVoid (builder);
2359 if (!lhs || ctx->is_dead [ins->sreg1]) {
2361 * The method did not set its return value, probably because it
2362 * ends with a throw.
2365 LLVMBuildRetVoid (builder);
2367 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2369 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2371 has_terminator = TRUE;
2377 case OP_ICOMPARE_IMM:
2378 case OP_LCOMPARE_IMM:
2379 case OP_COMPARE_IMM: {
2383 if (ins->next->opcode == OP_NOP)
2386 if (ins->next->opcode == OP_BR)
2387 /* The comparison result is not needed */
2390 rel = mono_opcode_to_cond (ins->next->opcode);
2392 if (ins->opcode == OP_ICOMPARE_IMM) {
2393 lhs = convert (ctx, lhs, LLVMInt32Type ());
2394 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2396 if (ins->opcode == OP_LCOMPARE_IMM) {
2397 lhs = convert (ctx, lhs, LLVMInt64Type ());
2398 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2400 if (ins->opcode == OP_LCOMPARE) {
2401 lhs = convert (ctx, lhs, LLVMInt64Type ());
2402 rhs = convert (ctx, rhs, LLVMInt64Type ());
2404 if (ins->opcode == OP_ICOMPARE) {
2405 lhs = convert (ctx, lhs, LLVMInt32Type ());
2406 rhs = convert (ctx, rhs, LLVMInt32Type ());
2410 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2411 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2412 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2413 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2416 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2417 if (ins->opcode == OP_FCOMPARE)
2418 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2419 else if (ins->opcode == OP_COMPARE_IMM)
2420 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2421 else if (ins->opcode == OP_LCOMPARE_IMM) {
2422 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2423 /* The immediate is encoded in two fields */
2424 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2425 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2427 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2430 else if (ins->opcode == OP_COMPARE)
2431 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2433 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2435 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2436 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2438 * If the target bb contains PHI instructions, LLVM requires
2439 * two PHI entries for this bblock, while we only generate one.
2440 * So convert this to an unconditional bblock. (bxc #171).
2442 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2444 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2446 has_terminator = TRUE;
2447 } else if (MONO_IS_SETCC (ins->next)) {
2448 sprintf (dname_buf, "t%d", ins->next->dreg);
2450 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2452 /* Add stores for volatile variables */
2453 emit_volatile_store (ctx, ins->next->dreg);
2454 } else if (MONO_IS_COND_EXC (ins->next)) {
2455 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2456 CHECK_FAILURE (ctx);
2457 builder = ctx->builder;
2459 LLVM_FAILURE (ctx, "next");
2473 rel = mono_opcode_to_cond (ins->opcode);
2475 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2476 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2484 gboolean empty = TRUE;
2486 /* Check that all input bblocks really branch to us */
2487 for (i = 0; i < bb->in_count; ++i) {
2488 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2489 ins->inst_phi_args [i + 1] = -1;
2495 /* LLVM doesn't like phi instructions with zero operands */
2496 ctx->is_dead [ins->dreg] = TRUE;
2500 /* Created earlier, insert it now */
2501 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2503 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2504 int sreg1 = ins->inst_phi_args [i + 1];
2508 * Count the number of times the incoming bblock branches to us,
2509 * since llvm requires a separate entry for each.
2511 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2512 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2515 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2516 if (switch_ins->inst_many_bb [j] == bb)
2523 /* Remember for later */
2524 for (j = 0; j < count; ++j) {
2525 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2528 node->in_bb = bb->in_bb [i];
2530 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);
2540 values [ins->dreg] = lhs;
2543 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2546 values [ins->dreg] = lhs;
2548 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2550 * This is added by the spilling pass in case of the JIT,
2551 * but we have to do it ourselves.
2553 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2587 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2588 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2590 switch (ins->opcode) {
2593 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2597 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2601 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2605 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2609 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2613 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2617 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2620 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2624 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2628 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2632 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2636 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2640 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2644 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2648 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2651 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2654 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2658 g_assert_not_reached ();
2665 case OP_IREM_UN_IMM:
2667 case OP_IDIV_UN_IMM:
2673 case OP_ISHR_UN_IMM:
2682 case OP_LSHR_UN_IMM:
2690 if (spec [MONO_INST_SRC1] == 'l') {
2691 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2693 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2696 #if SIZEOF_VOID_P == 4
2697 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2698 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2701 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2702 lhs = convert (ctx, lhs, IntPtrType ());
2703 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2704 switch (ins->opcode) {
2708 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2712 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2716 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2720 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2722 case OP_IDIV_UN_IMM:
2723 case OP_LDIV_UN_IMM:
2724 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2728 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2730 case OP_IREM_UN_IMM:
2731 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2736 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2740 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2744 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2749 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2754 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2756 case OP_ISHR_UN_IMM:
2757 /* This is used to implement conv.u4, so the lhs could be an i8 */
2758 lhs = convert (ctx, lhs, LLVMInt32Type ());
2759 imm = convert (ctx, imm, LLVMInt32Type ());
2760 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2762 case OP_LSHR_UN_IMM:
2763 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2766 g_assert_not_reached ();
2771 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2774 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2777 lhs = convert (ctx, lhs, LLVMDoubleType ());
2778 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2781 guint32 v = 0xffffffff;
2782 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2786 guint64 v = 0xffffffffffffffffLL;
2787 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2790 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2792 LLVMValueRef v1, v2;
2794 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2795 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2796 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2801 case OP_ICONV_TO_I1:
2802 case OP_ICONV_TO_I2:
2803 case OP_ICONV_TO_I4:
2804 case OP_ICONV_TO_U1:
2805 case OP_ICONV_TO_U2:
2806 case OP_ICONV_TO_U4:
2807 case OP_LCONV_TO_I1:
2808 case OP_LCONV_TO_I2:
2809 case OP_LCONV_TO_U1:
2810 case OP_LCONV_TO_U2:
2811 case OP_LCONV_TO_U4: {
2814 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);
2816 /* Have to do two casts since our vregs have type int */
2817 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2819 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2821 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2824 case OP_ICONV_TO_I8:
2825 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2827 case OP_ICONV_TO_U8:
2828 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2830 case OP_FCONV_TO_I4:
2831 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2833 case OP_FCONV_TO_I1:
2834 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2836 case OP_FCONV_TO_U1:
2837 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2839 case OP_FCONV_TO_I2:
2840 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2842 case OP_FCONV_TO_U2:
2843 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2845 case OP_FCONV_TO_I8:
2846 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2849 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2851 case OP_ICONV_TO_R8:
2852 case OP_LCONV_TO_R8:
2853 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2855 case OP_LCONV_TO_R_UN:
2856 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2858 #if SIZEOF_VOID_P == 4
2861 case OP_LCONV_TO_I4:
2862 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2864 case OP_ICONV_TO_R4:
2865 case OP_LCONV_TO_R4:
2866 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2867 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2869 case OP_FCONV_TO_R4:
2870 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2871 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2874 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2877 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2880 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2882 case OP_LOCALLOC_IMM: {
2885 guint32 size = ins->inst_imm;
2886 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2888 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2890 if (ins->flags & MONO_INST_INIT) {
2891 LLVMValueRef args [5];
2894 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2895 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2896 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2897 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2898 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2901 values [ins->dreg] = v;
2905 LLVMValueRef v, size;
2907 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), "");
2909 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2911 if (ins->flags & MONO_INST_INIT) {
2912 LLVMValueRef args [5];
2915 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2917 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2918 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2919 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2921 values [ins->dreg] = v;
2925 case OP_LOADI1_MEMBASE:
2926 case OP_LOADU1_MEMBASE:
2927 case OP_LOADI2_MEMBASE:
2928 case OP_LOADU2_MEMBASE:
2929 case OP_LOADI4_MEMBASE:
2930 case OP_LOADU4_MEMBASE:
2931 case OP_LOADI8_MEMBASE:
2932 case OP_LOADR4_MEMBASE:
2933 case OP_LOADR8_MEMBASE:
2934 case OP_LOAD_MEMBASE:
2942 LLVMValueRef base, index, addr;
2944 gboolean sext = FALSE, zext = FALSE;
2945 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2947 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2952 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)) {
2953 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2958 if (ins->inst_offset == 0) {
2960 } else if (ins->inst_offset % size != 0) {
2961 /* Unaligned load */
2962 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2963 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2965 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2966 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2970 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2972 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2974 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2976 * These will signal LLVM that these loads do not alias any stores, and
2977 * they can't fail, allowing them to be hoisted out of loops.
2979 set_metadata_flag (values [ins->dreg], "mono.noalias");
2980 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2984 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2986 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2987 else if (ins->opcode == OP_LOADR4_MEMBASE)
2988 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2992 case OP_STOREI1_MEMBASE_REG:
2993 case OP_STOREI2_MEMBASE_REG:
2994 case OP_STOREI4_MEMBASE_REG:
2995 case OP_STOREI8_MEMBASE_REG:
2996 case OP_STORER4_MEMBASE_REG:
2997 case OP_STORER8_MEMBASE_REG:
2998 case OP_STORE_MEMBASE_REG: {
3000 LLVMValueRef index, addr;
3002 gboolean sext = FALSE, zext = FALSE;
3003 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3005 if (!values [ins->inst_destbasereg])
3006 LLVM_FAILURE (ctx, "inst_destbasereg");
3008 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3010 if (ins->inst_offset % size != 0) {
3011 /* Unaligned store */
3012 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3013 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3015 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3016 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3018 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3022 case OP_STOREI1_MEMBASE_IMM:
3023 case OP_STOREI2_MEMBASE_IMM:
3024 case OP_STOREI4_MEMBASE_IMM:
3025 case OP_STOREI8_MEMBASE_IMM:
3026 case OP_STORE_MEMBASE_IMM: {
3028 LLVMValueRef index, addr;
3030 gboolean sext = FALSE, zext = FALSE;
3031 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3033 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3035 if (ins->inst_offset % size != 0) {
3036 /* Unaligned store */
3037 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3038 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3040 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3041 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3043 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3048 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3050 case OP_OUTARG_VTRETADDR:
3057 case OP_VOIDCALL_MEMBASE:
3058 case OP_CALL_MEMBASE:
3059 case OP_LCALL_MEMBASE:
3060 case OP_FCALL_MEMBASE:
3061 case OP_VCALL_MEMBASE:
3062 case OP_VOIDCALL_REG:
3066 case OP_VCALL_REG: {
3067 process_call (ctx, bb, &builder, ins);
3068 CHECK_FAILURE (ctx);
3073 LLVMValueRef indexes [2];
3075 LLVMValueRef got_entry_addr;
3078 * FIXME: Can't allocate from the cfg mempool since that is freed if
3079 * the LLVM compile fails.
3081 ji = g_new0 (MonoJumpInfo, 1);
3082 ji->type = (MonoJumpInfoType)ins->inst_i1;
3083 ji->data.target = ins->inst_p0;
3085 ji = mono_aot_patch_info_dup (ji);
3087 ji->next = cfg->patch_info;
3088 cfg->patch_info = ji;
3090 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3091 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3093 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3094 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3095 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3097 // FIXME: This doesn't work right now, because it must be
3098 // paired with an invariant.end, and even then, its only in effect
3099 // inside its basic block
3102 LLVMValueRef args [3];
3103 LLVMValueRef ptr, val;
3105 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3107 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3109 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3113 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3116 case OP_NOT_REACHED:
3117 LLVMBuildUnreachable (builder);
3118 has_terminator = TRUE;
3119 g_assert (bb->block_num < cfg->max_block_num);
3120 ctx->unreachable [bb->block_num] = TRUE;
3121 /* Might have instructions after this */
3123 MonoInst *next = ins->next;
3125 * FIXME: If later code uses the regs defined by these instructions,
3126 * compilation will fail.
3128 MONO_DELETE_INS (bb, next);
3132 MonoInst *var = ins->inst_p0;
3134 values [ins->dreg] = addresses [var->dreg];
3138 LLVMValueRef args [1];
3140 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3141 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3145 LLVMValueRef args [1];
3147 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3148 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3152 LLVMValueRef args [1];
3155 /* This no longer seems to happen */
3157 * LLVM optimizes sqrt(nan) into undefined in
3158 * lib/Analysis/ConstantFolding.cpp
3159 * Also, sqrt(NegativeInfinity) is optimized into 0.
3161 LLVM_FAILURE (ctx, "sqrt");
3163 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3164 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3168 LLVMValueRef args [1];
3170 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3171 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3185 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3186 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3188 switch (ins->opcode) {
3191 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3195 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3199 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3203 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3206 g_assert_not_reached ();
3209 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3212 case OP_ATOMIC_EXCHANGE_I4: {
3213 LLVMValueRef args [2];
3215 g_assert (ins->inst_offset == 0);
3217 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3220 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3223 case OP_ATOMIC_EXCHANGE_I8: {
3224 LLVMValueRef args [2];
3226 g_assert (ins->inst_offset == 0);
3228 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3229 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3230 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3233 case OP_ATOMIC_ADD_NEW_I4: {
3234 LLVMValueRef args [2];
3236 g_assert (ins->inst_offset == 0);
3238 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3240 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3243 case OP_ATOMIC_ADD_NEW_I8: {
3244 LLVMValueRef args [2];
3246 g_assert (ins->inst_offset == 0);
3248 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3249 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3250 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3253 case OP_ATOMIC_CAS_I4:
3254 case OP_ATOMIC_CAS_I8: {
3255 LLVMValueRef args [3];
3258 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3259 t = LLVMInt32Type ();
3261 t = LLVMInt64Type ();
3264 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3266 args [1] = convert (ctx, values [ins->sreg3], t);
3268 args [2] = convert (ctx, values [ins->sreg2], t);
3269 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3272 case OP_MEMORY_BARRIER: {
3273 mono_llvm_build_fence (builder);
3276 case OP_RELAXED_NOP: {
3277 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3278 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3285 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3287 // 257 == FS segment register
3288 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3290 // 256 == GS segment register
3291 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3295 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3297 LLVM_FAILURE (ctx, "opcode tls-get");
3307 case OP_IADD_OVF_UN:
3309 case OP_ISUB_OVF_UN:
3311 case OP_IMUL_OVF_UN:
3312 #if SIZEOF_VOID_P == 8
3314 case OP_LADD_OVF_UN:
3316 case OP_LSUB_OVF_UN:
3318 case OP_LMUL_OVF_UN:
3321 LLVMValueRef args [2], val, ovf, func;
3323 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3324 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3325 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3327 val = LLVMBuildCall (builder, func, args, 2, "");
3328 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3329 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3330 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3331 CHECK_FAILURE (ctx);
3332 builder = ctx->builder;
3338 * We currently model them using arrays. Promotion to local vregs is
3339 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3340 * so we always have an entry in cfg->varinfo for them.
3341 * FIXME: Is this needed ?
3344 MonoClass *klass = ins->klass;
3345 LLVMValueRef args [5];
3349 LLVM_FAILURE (ctx, "!klass");
3353 if (!addresses [ins->dreg])
3354 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3355 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3356 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3357 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3359 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3360 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3361 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3365 case OP_STOREV_MEMBASE:
3366 case OP_LOADV_MEMBASE:
3368 MonoClass *klass = ins->klass;
3369 LLVMValueRef src = NULL, dst, args [5];
3370 gboolean done = FALSE;
3374 LLVM_FAILURE (ctx, "!klass");
3378 if (mini_is_gsharedvt_klass (cfg, klass)) {
3380 LLVM_FAILURE (ctx, "gsharedvt");
3384 switch (ins->opcode) {
3385 case OP_STOREV_MEMBASE:
3386 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3387 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3388 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3391 if (!addresses [ins->sreg1]) {
3393 g_assert (values [ins->sreg1]);
3394 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));
3395 LLVMBuildStore (builder, values [ins->sreg1], dst);
3398 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3399 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3402 case OP_LOADV_MEMBASE:
3403 if (!addresses [ins->dreg])
3404 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3405 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3406 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3409 if (!addresses [ins->sreg1])
3410 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3411 if (!addresses [ins->dreg])
3412 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3413 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3414 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3417 g_assert_not_reached ();
3419 CHECK_FAILURE (ctx);
3426 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3427 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3429 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3430 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3431 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3434 case OP_LLVM_OUTARG_VT:
3435 if (!addresses [ins->sreg1]) {
3436 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3437 g_assert (values [ins->sreg1]);
3438 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3440 addresses [ins->dreg] = addresses [ins->sreg1];
3446 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3448 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3451 case OP_LOADX_MEMBASE: {
3452 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3455 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3456 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3459 case OP_STOREX_MEMBASE: {
3460 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3463 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3464 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3471 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3475 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3481 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3485 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3489 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3493 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3496 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3499 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3502 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3506 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3517 LLVMValueRef v = NULL;
3519 switch (ins->opcode) {
3524 t = LLVMVectorType (LLVMInt32Type (), 4);
3525 rt = LLVMVectorType (LLVMFloatType (), 4);
3531 t = LLVMVectorType (LLVMInt64Type (), 2);
3532 rt = LLVMVectorType (LLVMDoubleType (), 2);
3535 t = LLVMInt32Type ();
3536 rt = LLVMInt32Type ();
3537 g_assert_not_reached ();
3540 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3541 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3542 switch (ins->opcode) {
3545 v = LLVMBuildAnd (builder, lhs, rhs, "");
3549 v = LLVMBuildOr (builder, lhs, rhs, "");
3553 v = LLVMBuildXor (builder, lhs, rhs, "");
3557 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3560 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3584 case OP_PADDB_SAT_UN:
3585 case OP_PADDW_SAT_UN:
3586 case OP_PSUBB_SAT_UN:
3587 case OP_PSUBW_SAT_UN:
3595 case OP_PMULW_HIGH_UN: {
3596 LLVMValueRef args [2];
3601 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3608 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3612 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3620 case OP_EXTRACTX_U2:
3622 case OP_EXTRACT_U1: {
3624 gboolean zext = FALSE;
3626 t = simd_op_to_llvm_type (ins->opcode);
3628 switch (ins->opcode) {
3636 case OP_EXTRACTX_U2:
3641 t = LLVMInt32Type ();
3642 g_assert_not_reached ();
3645 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3646 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3648 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3657 case OP_EXPAND_R8: {
3658 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3659 LLVMValueRef mask [16], v;
3661 for (i = 0; i < 16; ++i)
3662 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3664 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3666 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3667 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3672 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3675 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3678 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3681 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3684 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3687 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3698 case OP_EXTRACT_MASK:
3705 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3707 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3711 case OP_ICONV_TO_R8_RAW:
3712 /* Same as OP_ICONV_TO_R8 */
3713 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3718 LLVMValueRef args [3];
3722 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3724 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3729 /* This is only used for implementing shifts by non-immediate */
3730 values [ins->dreg] = lhs;
3741 LLVMValueRef args [3];
3744 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3746 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3757 case OP_PSHLQ_REG: {
3758 LLVMValueRef args [3];
3761 args [1] = values [ins->sreg2];
3763 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3770 case OP_PSHUFLEW_LOW:
3771 case OP_PSHUFLEW_HIGH: {
3773 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3774 int i, mask_size = 0;
3775 int imask = ins->inst_c0;
3777 /* Convert the x86 shuffle mask to LLVM's */
3778 switch (ins->opcode) {
3781 mask [0] = ((imask >> 0) & 3);
3782 mask [1] = ((imask >> 2) & 3);
3783 mask [2] = ((imask >> 4) & 3) + 4;
3784 mask [3] = ((imask >> 6) & 3) + 4;
3785 v1 = values [ins->sreg1];
3786 v2 = values [ins->sreg2];
3790 mask [0] = ((imask >> 0) & 1);
3791 mask [1] = ((imask >> 1) & 1) + 2;
3792 v1 = values [ins->sreg1];
3793 v2 = values [ins->sreg2];
3795 case OP_PSHUFLEW_LOW:
3797 mask [0] = ((imask >> 0) & 3);
3798 mask [1] = ((imask >> 2) & 3);
3799 mask [2] = ((imask >> 4) & 3);
3800 mask [3] = ((imask >> 6) & 3);
3805 v1 = values [ins->sreg1];
3806 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3808 case OP_PSHUFLEW_HIGH:
3814 mask [4] = 4 + ((imask >> 0) & 3);
3815 mask [5] = 4 + ((imask >> 2) & 3);
3816 mask [6] = 4 + ((imask >> 4) & 3);
3817 mask [7] = 4 + ((imask >> 6) & 3);
3818 v1 = values [ins->sreg1];
3819 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3823 mask [0] = ((imask >> 0) & 3);
3824 mask [1] = ((imask >> 2) & 3);
3825 mask [2] = ((imask >> 4) & 3);
3826 mask [3] = ((imask >> 6) & 3);
3827 v1 = values [ins->sreg1];
3828 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3831 g_assert_not_reached ();
3833 for (i = 0; i < mask_size; ++i)
3834 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3836 values [ins->dreg] =
3837 LLVMBuildShuffleVector (builder, v1, v2,
3838 LLVMConstVector (mask_values, mask_size), dname);
3842 case OP_UNPACK_LOWB:
3843 case OP_UNPACK_LOWW:
3844 case OP_UNPACK_LOWD:
3845 case OP_UNPACK_LOWQ:
3846 case OP_UNPACK_LOWPS:
3847 case OP_UNPACK_LOWPD:
3848 case OP_UNPACK_HIGHB:
3849 case OP_UNPACK_HIGHW:
3850 case OP_UNPACK_HIGHD:
3851 case OP_UNPACK_HIGHQ:
3852 case OP_UNPACK_HIGHPS:
3853 case OP_UNPACK_HIGHPD: {
3855 LLVMValueRef mask_values [16];
3856 int i, mask_size = 0;
3857 gboolean low = FALSE;
3859 switch (ins->opcode) {
3860 case OP_UNPACK_LOWB:
3864 case OP_UNPACK_LOWW:
3868 case OP_UNPACK_LOWD:
3869 case OP_UNPACK_LOWPS:
3873 case OP_UNPACK_LOWQ:
3874 case OP_UNPACK_LOWPD:
3878 case OP_UNPACK_HIGHB:
3881 case OP_UNPACK_HIGHW:
3884 case OP_UNPACK_HIGHD:
3885 case OP_UNPACK_HIGHPS:
3888 case OP_UNPACK_HIGHQ:
3889 case OP_UNPACK_HIGHPD:
3893 g_assert_not_reached ();
3897 for (i = 0; i < (mask_size / 2); ++i) {
3899 mask [(i * 2) + 1] = mask_size + i;
3902 for (i = 0; i < (mask_size / 2); ++i) {
3903 mask [(i * 2)] = (mask_size / 2) + i;
3904 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3908 for (i = 0; i < mask_size; ++i)
3909 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3911 values [ins->dreg] =
3912 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3913 LLVMConstVector (mask_values, mask_size), dname);
3918 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3919 LLVMValueRef v, val;
3921 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3922 val = LLVMConstNull (t);
3923 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3924 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3926 values [ins->dreg] = val;
3930 case OP_DUPPS_HIGH: {
3931 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3932 LLVMValueRef v1, v2, val;
3935 if (ins->opcode == OP_DUPPS_LOW) {
3936 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3937 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3939 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3940 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3942 val = LLVMConstNull (t);
3943 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3944 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3945 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3946 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3948 values [ins->dreg] = val;
3958 * EXCEPTION HANDLING
3960 case OP_IMPLICIT_EXCEPTION:
3961 /* This marks a place where an implicit exception can happen */
3962 if (bb->region != -1)
3963 LLVM_FAILURE (ctx, "implicit-exception");
3967 MonoMethodSignature *throw_sig;
3968 LLVMValueRef callee, arg;
3969 gboolean rethrow = (ins->opcode == OP_RETHROW);
3970 const char *icall_name;
3972 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3973 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3976 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3977 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3978 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3979 if (cfg->compile_aot) {
3980 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3982 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3986 * LLVM doesn't push the exception argument, so we need a different
3989 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3991 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3995 mono_memory_barrier ();
3997 ctx->lmodule->rethrow = callee;
3999 ctx->lmodule->throw = callee;
4001 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4002 emit_call (ctx, bb, &builder, callee, &arg, 1);
4005 case OP_CALL_HANDLER: {
4007 * We don't 'call' handlers, but instead simply branch to them.
4008 * The code generated by ENDFINALLY will branch back to us.
4010 LLVMBasicBlockRef noex_bb;
4012 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4014 bb_list = info->call_handler_return_bbs;
4017 * Set the indicator variable for the finally clause.
4019 lhs = info->finally_ind;
4021 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4023 /* Branch to the finally clause */
4024 LLVMBuildBr (builder, info->call_handler_target_bb);
4026 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4027 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4029 builder = ctx->builder = create_builder (ctx);
4030 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4032 bblocks [bb->block_num].end_bblock = noex_bb;
4035 case OP_START_HANDLER: {
4038 case OP_ENDFINALLY: {
4039 LLVMBasicBlockRef resume_bb;
4040 MonoBasicBlock *handler_bb;
4041 LLVMValueRef val, switch_ins, callee;
4045 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4046 g_assert (handler_bb);
4047 info = &bblocks [handler_bb->block_num];
4048 lhs = info->finally_ind;
4051 bb_list = info->call_handler_return_bbs;
4053 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4055 /* Load the finally variable */
4056 val = LLVMBuildLoad (builder, lhs, "");
4058 /* Reset the variable */
4059 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4061 /* Branch to either resume_bb, or to the bblocks in bb_list */
4062 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4064 * The other targets are added at the end to handle OP_CALL_HANDLER
4065 * opcodes processed later.
4067 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4069 builder = ctx->builder = create_builder (ctx);
4070 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4072 if (ctx->cfg->compile_aot) {
4073 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4075 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4077 LLVMBuildCall (builder, callee, NULL, 0, "");
4079 LLVMBuildUnreachable (builder);
4080 has_terminator = TRUE;
4086 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4087 LLVM_FAILURE (ctx, reason);
4092 /* Convert the value to the type required by phi nodes */
4093 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4094 if (!values [ins->dreg])
4096 values [ins->dreg] = addresses [ins->dreg];
4098 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4101 /* Add stores for volatile variables */
4102 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4103 emit_volatile_store (ctx, ins->dreg);
4106 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4107 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4109 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4110 LLVMBuildRetVoid (builder);
4112 if (bb == cfg->bb_entry)
4113 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4122 * mono_llvm_check_method_supported:
4124 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4125 * compiling a method twice.
4128 mono_llvm_check_method_supported (MonoCompile *cfg)
4130 MonoMethodHeader *header = cfg->header;
4131 MonoExceptionClause *clause;
4134 if (cfg->method->save_lmf) {
4135 cfg->exception_message = g_strdup ("lmf");
4136 cfg->disable_llvm = TRUE;
4140 for (i = 0; i < header->num_clauses; ++i) {
4141 clause = &header->clauses [i];
4143 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4145 * FIXME: Some tests still fail with nested clauses.
4147 cfg->exception_message = g_strdup ("nested clauses");
4148 cfg->disable_llvm = TRUE;
4154 if (cfg->method->dynamic) {
4155 cfg->exception_message = g_strdup ("dynamic.");
4156 cfg->disable_llvm = TRUE;
4161 * mono_llvm_emit_method:
4163 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4166 mono_llvm_emit_method (MonoCompile *cfg)
4169 MonoMethodSignature *sig;
4171 LLVMTypeRef method_type;
4172 LLVMValueRef method = NULL;
4174 LLVMValueRef *values;
4175 int i, max_block_num, bb_index;
4176 gboolean last = FALSE;
4177 GPtrArray *phi_values;
4178 LLVMCallInfo *linfo;
4180 LLVMModuleRef module;
4182 GPtrArray *bblock_list;
4183 MonoMethodHeader *header;
4184 MonoExceptionClause *clause;
4188 /* The code below might acquire the loader lock, so use it for global locking */
4189 mono_loader_lock ();
4191 /* Used to communicate with the callbacks */
4192 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4194 ctx = g_new0 (EmitContext, 1);
4196 ctx->mempool = cfg->mempool;
4199 * This maps vregs to the LLVM instruction defining them
4201 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4203 * This maps vregs for volatile variables to the LLVM instruction defining their
4206 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4207 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4208 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4209 phi_values = g_ptr_array_new ();
4211 * This signals whenever the vreg was defined by a phi node with no input vars
4212 * (i.e. all its input bblocks end with NOT_REACHABLE).
4214 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4215 /* Whenever the bblock is unreachable */
4216 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4218 bblock_list = g_ptr_array_new ();
4220 ctx->values = values;
4221 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4223 if (cfg->compile_aot) {
4224 ctx->lmodule = &aot_module;
4225 method_name = mono_aot_get_method_name (cfg);
4226 cfg->llvm_method_name = g_strdup (method_name);
4229 ctx->lmodule = &jit_module;
4230 method_name = mono_method_full_name (cfg->method, TRUE);
4233 module = ctx->module = ctx->lmodule->module;
4237 static int count = 0;
4240 if (getenv ("LLVM_COUNT")) {
4241 if (count == atoi (getenv ("LLVM_COUNT"))) {
4242 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4246 if (count > atoi (getenv ("LLVM_COUNT")))
4247 LLVM_FAILURE (ctx, "");
4252 sig = mono_method_signature (cfg->method);
4255 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4257 CHECK_FAILURE (ctx);
4260 linfo->rgctx_arg = TRUE;
4261 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4262 CHECK_FAILURE (ctx);
4265 * This maps parameter indexes in the original signature to the indexes in
4266 * the LLVM signature.
4268 ctx->pindexes = sinfo.pindexes;
4270 method = LLVMAddFunction (module, method_name, method_type);
4271 ctx->lmethod = method;
4273 #ifdef LLVM_MONO_BRANCH
4274 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4276 LLVMSetLinkage (method, LLVMPrivateLinkage);
4278 LLVMAddFunctionAttr (method, LLVMUWTable);
4280 if (cfg->compile_aot) {
4281 LLVMSetLinkage (method, LLVMInternalLinkage);
4282 LLVMSetVisibility (method, LLVMHiddenVisibility);
4284 LLVMSetLinkage (method, LLVMPrivateLinkage);
4287 if (cfg->method->save_lmf)
4288 LLVM_FAILURE (ctx, "lmf");
4290 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4291 LLVM_FAILURE (ctx, "pinvoke signature");
4293 header = cfg->header;
4294 for (i = 0; i < header->num_clauses; ++i) {
4295 clause = &header->clauses [i];
4296 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4297 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4300 if (linfo->rgctx_arg) {
4301 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4303 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4304 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4305 * CC_X86_64_Mono in X86CallingConv.td.
4307 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4308 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4310 if (cfg->vret_addr) {
4311 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4312 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4315 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4316 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4319 names = g_new (char *, sig->param_count);
4320 mono_method_get_param_names (cfg->method, (const char **) names);
4322 for (i = 0; i < sig->param_count; ++i) {
4325 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4326 if (names [i] && names [i][0] != '\0')
4327 name = g_strdup_printf ("arg_%s", names [i]);
4329 name = g_strdup_printf ("arg_%d", i);
4330 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4332 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4333 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4338 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4339 max_block_num = MAX (max_block_num, bb->block_num);
4340 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4342 /* Add branches between non-consecutive bblocks */
4343 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4344 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4345 bb->next_bb != bb->last_ins->inst_false_bb) {
4347 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4348 inst->opcode = OP_BR;
4349 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4350 mono_bblock_add_inst (bb, inst);
4355 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4356 * was later optimized away, so clear these flags, and add them back for the still
4357 * present OP_LDADDR instructions.
4359 for (i = 0; i < cfg->next_vreg; ++i) {
4362 ins = get_vreg_to_inst (cfg, i);
4363 if (ins && ins != cfg->rgctx_var)
4364 ins->flags &= ~MONO_INST_INDIRECT;
4368 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4370 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4372 LLVMBuilderRef builder;
4374 char dname_buf[128];
4376 builder = create_builder (ctx);
4378 for (ins = bb->code; ins; ins = ins->next) {
4379 switch (ins->opcode) {
4384 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4386 CHECK_FAILURE (ctx);
4388 if (ins->opcode == OP_VPHI) {
4389 /* Treat valuetype PHI nodes as operating on the address itself */
4390 g_assert (ins->klass);
4391 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4395 * Have to precreate these, as they can be referenced by
4396 * earlier instructions.
4398 sprintf (dname_buf, "t%d", ins->dreg);
4400 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4402 if (ins->opcode == OP_VPHI)
4403 ctx->addresses [ins->dreg] = values [ins->dreg];
4405 g_ptr_array_add (phi_values, values [ins->dreg]);
4408 * Set the expected type of the incoming arguments since these have
4409 * to have the same type.
4411 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4412 int sreg1 = ins->inst_phi_args [i + 1];
4415 ctx->vreg_types [sreg1] = phi_type;
4420 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4429 * Create an ordering for bblocks, use the depth first order first, then
4430 * put the exception handling bblocks last.
4432 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4433 bb = cfg->bblocks [bb_index];
4434 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4435 g_ptr_array_add (bblock_list, bb);
4436 bblocks [bb->block_num].added = TRUE;
4440 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4441 if (!bblocks [bb->block_num].added)
4442 g_ptr_array_add (bblock_list, bb);
4446 * Second pass: generate code.
4448 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4449 bb = g_ptr_array_index (bblock_list, bb_index);
4451 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4454 process_bb (ctx, bb);
4455 CHECK_FAILURE (ctx);
4458 /* Add incoming phi values */
4459 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4460 GSList *l, *ins_list;
4462 ins_list = bblocks [bb->block_num].phi_nodes;
4464 for (l = ins_list; l; l = l->next) {
4465 PhiNode *node = l->data;
4466 MonoInst *phi = node->phi;
4467 int sreg1 = node->sreg;
4468 LLVMBasicBlockRef in_bb;
4473 in_bb = get_end_bb (ctx, node->in_bb);
4475 if (ctx->unreachable [node->in_bb->block_num])
4478 if (!values [sreg1])
4479 /* Can happen with values in EH clauses */
4480 LLVM_FAILURE (ctx, "incoming phi sreg1");
4482 if (phi->opcode == OP_VPHI) {
4483 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4484 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4486 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4487 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4492 /* Create the SWITCH statements for ENDFINALLY instructions */
4493 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4494 BBInfo *info = &bblocks [bb->block_num];
4496 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4497 LLVMValueRef switch_ins = l->data;
4498 GSList *bb_list = info->call_handler_return_bbs;
4500 for (i = 0; i < g_slist_length (bb_list); ++i)
4501 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4505 if (cfg->verbose_level > 1)
4506 mono_llvm_dump_value (method);
4508 mark_as_used (module, method);
4510 if (cfg->compile_aot) {
4511 /* Don't generate native code, keep the LLVM IR */
4512 if (cfg->compile_aot && cfg->verbose_level)
4513 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4515 //LLVMVerifyFunction(method, 0);
4517 mono_llvm_optimize_method (method);
4519 if (cfg->verbose_level > 1)
4520 mono_llvm_dump_value (method);
4522 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4524 /* Set by emit_cb */
4525 g_assert (cfg->code_len);
4527 /* FIXME: Free the LLVM IL for the function */
4535 /* Need to add unused phi nodes as they can be referenced by other values */
4536 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4537 LLVMBuilderRef builder;
4539 builder = create_builder (ctx);
4540 LLVMPositionBuilderAtEnd (builder, phi_bb);
4542 for (i = 0; i < phi_values->len; ++i) {
4543 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4544 if (LLVMGetInstructionParent (v) == NULL)
4545 LLVMInsertIntoBuilder (builder, v);
4548 LLVMDeleteFunction (method);
4553 g_free (ctx->addresses);
4554 g_free (ctx->vreg_types);
4555 g_free (ctx->vreg_cli_types);
4556 g_free (ctx->pindexes);
4557 g_free (ctx->is_dead);
4558 g_free (ctx->unreachable);
4559 g_ptr_array_free (phi_values, TRUE);
4560 g_free (ctx->bblocks);
4561 g_hash_table_destroy (ctx->region_to_handler);
4562 g_free (method_name);
4563 g_ptr_array_free (bblock_list, TRUE);
4565 for (l = ctx->builders; l; l = l->next) {
4566 LLVMBuilderRef builder = l->data;
4567 LLVMDisposeBuilder (builder);
4572 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4574 mono_loader_unlock ();
4578 * mono_llvm_emit_call:
4580 * Same as mono_arch_emit_call () for LLVM.
4583 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4586 MonoMethodSignature *sig;
4587 int i, n, stack_size;
4592 sig = call->signature;
4593 n = sig->param_count + sig->hasthis;
4595 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4597 if (cfg->disable_llvm)
4600 if (sig->call_convention == MONO_CALL_VARARG) {
4601 cfg->exception_message = g_strdup ("varargs");
4602 cfg->disable_llvm = TRUE;
4605 for (i = 0; i < n; ++i) {
4608 ainfo = call->cinfo->args + i;
4610 in = call->args [i];
4612 /* Simply remember the arguments */
4613 switch (ainfo->storage) {
4615 case LLVMArgInFPReg: {
4616 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4618 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4619 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4620 ins->dreg = mono_alloc_freg (cfg);
4622 MONO_INST_NEW (cfg, ins, OP_MOVE);
4623 ins->dreg = mono_alloc_ireg (cfg);
4625 ins->sreg1 = in->dreg;
4628 case LLVMArgVtypeByVal:
4629 case LLVMArgVtypeInReg:
4630 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4631 ins->dreg = mono_alloc_ireg (cfg);
4632 ins->sreg1 = in->dreg;
4633 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4636 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4637 cfg->exception_message = g_strdup ("ainfo->storage");
4638 cfg->disable_llvm = TRUE;
4642 if (!cfg->disable_llvm) {
4643 MONO_ADD_INS (cfg->cbb, ins);
4644 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4649 static unsigned char*
4650 alloc_cb (LLVMValueRef function, int size)
4654 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4658 return mono_domain_code_reserve (cfg->domain, size);
4660 return mono_domain_code_reserve (mono_domain_get (), size);
4665 emitted_cb (LLVMValueRef function, void *start, void *end)
4669 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4671 cfg->code_len = (guint8*)end - (guint8*)start;
4675 exception_cb (void *data)
4678 MonoJitExceptionInfo *ei;
4679 guint32 ei_len, i, j, nested_len, nindex;
4680 gpointer *type_info;
4681 int this_reg, this_offset;
4683 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4687 * data points to a DWARF FDE structure, convert it to our unwind format and
4689 * An alternative would be to save it directly, and modify our unwinder to work
4692 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);
4694 /* Count nested clauses */
4696 for (i = 0; i < ei_len; ++i) {
4697 for (j = 0; j < ei_len; ++j) {
4698 gint32 cindex1 = *(gint32*)type_info [i];
4699 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4700 gint32 cindex2 = *(gint32*)type_info [j];
4701 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4703 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4709 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4710 cfg->llvm_ex_info_len = ei_len + nested_len;
4711 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4712 /* Fill the rest of the information from the type info */
4713 for (i = 0; i < ei_len; ++i) {
4714 gint32 clause_index = *(gint32*)type_info [i];
4715 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4717 cfg->llvm_ex_info [i].flags = clause->flags;
4718 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4722 * For nested clauses, the LLVM produced exception info associates the try interval with
4723 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4725 /* FIXME: These should be order with the normal clauses */
4727 for (i = 0; i < ei_len; ++i) {
4728 for (j = 0; j < ei_len; ++j) {
4729 gint32 cindex1 = *(gint32*)type_info [i];
4730 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4731 gint32 cindex2 = *(gint32*)type_info [j];
4732 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4734 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4736 * The try interval comes from the nested clause, everything else from the
4739 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4740 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4741 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4746 g_assert (nindex == ei_len + nested_len);
4747 cfg->llvm_this_reg = this_reg;
4748 cfg->llvm_this_offset = this_offset;
4750 /* type_info [i] is cfg mempool allocated, no need to free it */
4757 dlsym_cb (const char *name, void **symbol)
4763 if (!strcmp (name, "__bzero")) {
4764 *symbol = (void*)bzero;
4766 current = mono_dl_open (NULL, 0, NULL);
4769 err = mono_dl_symbol (current, name, symbol);
4771 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4772 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4778 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4780 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4784 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4786 LLVMTypeRef param_types [4];
4788 param_types [0] = param_type1;
4789 param_types [1] = param_type2;
4791 AddFunc (module, name, ret_type, param_types, 2);
4795 add_intrinsics (LLVMModuleRef module)
4797 /* Emit declarations of instrinsics */
4799 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4800 * type doesn't seem to do any locking.
4803 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4805 memset_param_count = 5;
4806 memset_func_name = "llvm.memset.p0i8.i32";
4808 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4812 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4814 memcpy_param_count = 5;
4815 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4817 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4821 LLVMTypeRef params [] = { LLVMDoubleType () };
4823 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4824 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4825 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4827 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4828 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4832 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4833 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4835 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4836 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4837 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4838 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4839 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4840 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4844 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4845 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4847 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4848 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4849 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4850 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4851 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4852 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4856 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4857 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4858 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4860 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4862 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4867 LLVMTypeRef arg_types [2];
4868 LLVMTypeRef ret_type;
4870 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4871 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4872 ret_type = LLVMInt32Type ();
4874 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4876 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4879 /* SSE intrinsics */
4881 LLVMTypeRef ret_type, arg_types [16];
4884 ret_type = type_to_simd_type (MONO_TYPE_I4);
4885 arg_types [0] = ret_type;
4886 arg_types [1] = ret_type;
4887 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4888 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4890 ret_type = type_to_simd_type (MONO_TYPE_I2);
4891 arg_types [0] = ret_type;
4892 arg_types [1] = ret_type;
4893 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4894 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4895 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4896 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4897 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4898 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4899 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4900 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4901 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4902 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4904 ret_type = type_to_simd_type (MONO_TYPE_I1);
4905 arg_types [0] = ret_type;
4906 arg_types [1] = ret_type;
4907 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4908 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4909 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4910 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4911 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4912 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4913 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4915 ret_type = type_to_simd_type (MONO_TYPE_R8);
4916 arg_types [0] = ret_type;
4917 arg_types [1] = ret_type;
4918 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4919 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4920 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4921 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4922 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4924 ret_type = type_to_simd_type (MONO_TYPE_R4);
4925 arg_types [0] = ret_type;
4926 arg_types [1] = ret_type;
4927 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4928 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4930 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4931 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4934 ret_type = type_to_simd_type (MONO_TYPE_I1);
4935 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4936 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4937 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4938 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4939 ret_type = type_to_simd_type (MONO_TYPE_I2);
4940 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4941 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4942 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4943 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4946 ret_type = type_to_simd_type (MONO_TYPE_R8);
4947 arg_types [0] = ret_type;
4948 arg_types [1] = ret_type;
4949 arg_types [2] = LLVMInt8Type ();
4950 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4951 ret_type = type_to_simd_type (MONO_TYPE_R4);
4952 arg_types [0] = ret_type;
4953 arg_types [1] = ret_type;
4954 arg_types [2] = LLVMInt8Type ();
4955 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4957 /* Conversion ops */
4958 ret_type = type_to_simd_type (MONO_TYPE_R8);
4959 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4960 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4961 ret_type = type_to_simd_type (MONO_TYPE_R4);
4962 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4963 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4964 ret_type = type_to_simd_type (MONO_TYPE_I4);
4965 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4966 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4967 ret_type = type_to_simd_type (MONO_TYPE_I4);
4968 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4969 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4970 ret_type = type_to_simd_type (MONO_TYPE_R4);
4971 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4972 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4973 ret_type = type_to_simd_type (MONO_TYPE_R8);
4974 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4975 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4977 ret_type = type_to_simd_type (MONO_TYPE_I4);
4978 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4979 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4980 ret_type = type_to_simd_type (MONO_TYPE_I4);
4981 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4982 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4985 ret_type = type_to_simd_type (MONO_TYPE_R8);
4986 arg_types [0] = ret_type;
4987 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
4988 ret_type = type_to_simd_type (MONO_TYPE_R4);
4989 arg_types [0] = ret_type;
4990 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
4991 ret_type = type_to_simd_type (MONO_TYPE_R4);
4992 arg_types [0] = ret_type;
4993 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
4994 ret_type = type_to_simd_type (MONO_TYPE_R4);
4995 arg_types [0] = ret_type;
4996 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
4999 ret_type = type_to_simd_type (MONO_TYPE_I2);
5000 arg_types [0] = ret_type;
5001 arg_types [1] = LLVMInt32Type ();
5002 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5003 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5004 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5005 ret_type = type_to_simd_type (MONO_TYPE_I4);
5006 arg_types [0] = ret_type;
5007 arg_types [1] = LLVMInt32Type ();
5008 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5009 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5010 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5011 ret_type = type_to_simd_type (MONO_TYPE_I8);
5012 arg_types [0] = ret_type;
5013 arg_types [1] = LLVMInt32Type ();
5014 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5015 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5018 ret_type = LLVMInt32Type ();
5019 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5020 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5023 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5025 /* Load/Store intrinsics */
5027 LLVMTypeRef arg_types [5];
5031 for (i = 1; i <= 8; i *= 2) {
5032 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5033 arg_types [1] = LLVMInt32Type ();
5034 arg_types [2] = LLVMInt1Type ();
5035 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5036 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5038 arg_types [0] = LLVMIntType (i * 8);
5039 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5040 arg_types [2] = LLVMInt32Type ();
5041 arg_types [3] = LLVMInt1Type ();
5042 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5043 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5049 mono_llvm_init (void)
5051 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5055 init_jit_module (void)
5057 MonoJitICallInfo *info;
5059 if (jit_module_inited)
5062 mono_loader_lock ();
5064 if (jit_module_inited) {
5065 mono_loader_unlock ();
5069 jit_module.module = LLVMModuleCreateWithName ("mono");
5071 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5073 add_intrinsics (jit_module.module);
5075 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5077 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5079 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5081 jit_module_inited = TRUE;
5083 mono_loader_unlock ();
5087 mono_llvm_cleanup (void)
5090 mono_llvm_dispose_ee (ee);
5092 if (jit_module.llvm_types)
5093 g_hash_table_destroy (jit_module.llvm_types);
5095 if (aot_module.module)
5096 LLVMDisposeModule (aot_module.module);
5098 LLVMContextDispose (LLVMGetGlobalContext ());
5102 mono_llvm_create_aot_module (const char *got_symbol)
5104 /* Delete previous module */
5105 if (aot_module.plt_entries)
5106 g_hash_table_destroy (aot_module.plt_entries);
5107 if (aot_module.module)
5108 LLVMDisposeModule (aot_module.module);
5110 memset (&aot_module, 0, sizeof (aot_module));
5112 aot_module.module = LLVMModuleCreateWithName ("aot");
5113 aot_module.got_symbol = got_symbol;
5115 add_intrinsics (aot_module.module);
5119 * We couldn't compute the type of the LLVM global representing the got because
5120 * its size is only known after all the methods have been emitted. So create
5121 * a dummy variable, and replace all uses it with the real got variable when
5122 * its size is known in mono_llvm_emit_aot_module ().
5125 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5127 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5128 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5131 /* Add a dummy personality function */
5133 LLVMBasicBlockRef lbb;
5134 LLVMBuilderRef lbuilder;
5135 LLVMValueRef personality;
5137 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5138 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5139 lbb = LLVMAppendBasicBlock (personality, "BB0");
5140 lbuilder = LLVMCreateBuilder ();
5141 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5142 LLVMBuildRetVoid (lbuilder);
5145 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5146 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5150 * Emit the aot module into the LLVM bitcode file FILENAME.
5153 mono_llvm_emit_aot_module (const char *filename, int got_size)
5155 LLVMTypeRef got_type;
5156 LLVMValueRef real_got;
5159 * Create the real got variable and replace all uses of the dummy variable with
5162 got_type = LLVMArrayType (IntPtrType (), got_size);
5163 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5164 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5165 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5167 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5169 mark_as_used (aot_module.module, real_got);
5171 /* Delete the dummy got so it doesn't become a global */
5172 LLVMDeleteGlobal (aot_module.got_var);
5178 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5179 g_assert_not_reached ();
5184 LLVMWriteBitcodeToFile (aot_module.module, filename);
5189 - Emit LLVM IR from the mono IR using the LLVM C API.
5190 - The original arch specific code remains, so we can fall back to it if we run
5191 into something we can't handle.
5195 A partial list of issues:
5196 - Handling of opcodes which can throw exceptions.
5198 In the mono JIT, these are implemented using code like this:
5205 push throw_pos - method
5206 call <exception trampoline>
5208 The problematic part is push throw_pos - method, which cannot be represented
5209 in the LLVM IR, since it does not support label values.
5210 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5211 be implemented in JIT mode ?
5212 -> a possible but slower implementation would use the normal exception
5213 throwing code but it would need to control the placement of the throw code
5214 (it needs to be exactly after the compare+branch).
5215 -> perhaps add a PC offset intrinsics ?
5217 - efficient implementation of .ovf opcodes.
5219 These are currently implemented as:
5220 <ins which sets the condition codes>
5223 Some overflow opcodes are now supported by LLVM SVN.
5225 - exception handling, unwinding.
5226 - SSA is disabled for methods with exception handlers
5227 - How to obtain unwind info for LLVM compiled methods ?
5228 -> this is now solved by converting the unwind info generated by LLVM
5230 - LLVM uses the c++ exception handling framework, while we use our home grown
5231 code, and couldn't use the c++ one:
5232 - its not supported under VC++, other exotic platforms.
5233 - it might be impossible to support filter clauses with it.
5237 The trampolines need a predictable call sequence, since they need to disasm
5238 the calling code to obtain register numbers / offsets.
5240 LLVM currently generates this code in non-JIT mode:
5241 mov -0x98(%rax),%eax
5243 Here, the vtable pointer is lost.
5244 -> solution: use one vtable trampoline per class.
5246 - passing/receiving the IMT pointer/RGCTX.
5247 -> solution: pass them as normal arguments ?
5251 LLVM does not allow the specification of argument registers etc. This means
5252 that all calls are made according to the platform ABI.
5254 - passing/receiving vtypes.
5256 Vtypes passed/received in registers are handled by the front end by using
5257 a signature with scalar arguments, and loading the parts of the vtype into those
5260 Vtypes passed on the stack are handled using the 'byval' attribute.
5264 Supported though alloca, we need to emit the load/store code.
5268 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5269 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5270 This is made easier because the IR is already in SSA form.
5271 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5272 types are frequently used incorrectly.
5277 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5278 append the AOT data structures to that file. For methods which cannot be
5279 handled by LLVM, the normal JIT compiled versions are used.
5282 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5283 * - each bblock should end with a branch
5284 * - setting the return value, making cfg->ret non-volatile
5285 * - avoid some transformations in the JIT which make it harder for us to generate
5287 * - use pointer types to help optimizations.