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 return IntPtrType ();
334 case MONO_TYPE_GENERICINST:
335 if (!mono_type_generic_inst_is_valuetype (t))
336 return IntPtrType ();
338 case MONO_TYPE_VALUETYPE:
339 case MONO_TYPE_TYPEDBYREF: {
343 klass = mono_class_from_mono_type (t);
345 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
346 return simd_class_to_llvm_type (ctx, klass);
349 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
350 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
353 LLVMTypeRef *eltypes;
356 size = get_vtype_size (t);
358 eltypes = g_new (LLVMTypeRef, size);
359 for (i = 0; i < size; ++i)
360 eltypes [i] = LLVMInt8Type ();
362 name = mono_type_full_name (&klass->byval_arg);
363 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
364 LLVMStructSetBody (ltype, eltypes, size, FALSE);
365 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
372 printf ("X: %d\n", t->type);
373 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
374 ctx->cfg->disable_llvm = TRUE;
382 * Return whenever T is an unsigned int type.
385 type_is_unsigned (EmitContext *ctx, MonoType *t)
401 * type_to_llvm_arg_type:
403 * Same as type_to_llvm_type, but treat i8/i16 as i32.
406 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
408 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
410 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
412 * LLVM generates code which only sets the lower bits, while JITted
413 * code expects all the bits to be set.
415 ptype = LLVMInt32Type ();
422 * llvm_type_to_stack_type:
424 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
427 static G_GNUC_UNUSED LLVMTypeRef
428 llvm_type_to_stack_type (LLVMTypeRef type)
432 if (type == LLVMInt8Type ())
433 return LLVMInt32Type ();
434 else if (type == LLVMInt16Type ())
435 return LLVMInt32Type ();
436 else if (type == LLVMFloatType ())
437 return LLVMDoubleType ();
443 * regtype_to_llvm_type:
445 * Return the LLVM type corresponding to the regtype C used in instruction
449 regtype_to_llvm_type (char c)
453 return LLVMInt32Type ();
455 return LLVMInt64Type ();
457 return LLVMDoubleType ();
466 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
469 op_to_llvm_type (int opcode)
474 return LLVMInt8Type ();
477 return LLVMInt8Type ();
480 return LLVMInt16Type ();
483 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt32Type ();
491 return LLVMInt64Type ();
493 return LLVMFloatType ();
495 return LLVMDoubleType ();
497 return LLVMInt64Type ();
499 return LLVMInt32Type ();
501 return LLVMInt64Type ();
504 return LLVMInt8Type ();
507 return LLVMInt16Type ();
510 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
517 return LLVMInt32Type ();
524 return LLVMInt64Type ();
526 printf ("%s\n", mono_inst_name (opcode));
527 g_assert_not_reached ();
533 * load_store_to_llvm_type:
535 * Return the size/sign/zero extension corresponding to the load/store opcode
539 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
545 case OP_LOADI1_MEMBASE:
546 case OP_STOREI1_MEMBASE_REG:
547 case OP_STOREI1_MEMBASE_IMM:
550 return LLVMInt8Type ();
551 case OP_LOADU1_MEMBASE:
555 return LLVMInt8Type ();
556 case OP_LOADI2_MEMBASE:
557 case OP_STOREI2_MEMBASE_REG:
558 case OP_STOREI2_MEMBASE_IMM:
561 return LLVMInt16Type ();
562 case OP_LOADU2_MEMBASE:
566 return LLVMInt16Type ();
567 case OP_LOADI4_MEMBASE:
568 case OP_LOADU4_MEMBASE:
571 case OP_STOREI4_MEMBASE_REG:
572 case OP_STOREI4_MEMBASE_IMM:
574 return LLVMInt32Type ();
575 case OP_LOADI8_MEMBASE:
577 case OP_STOREI8_MEMBASE_REG:
578 case OP_STOREI8_MEMBASE_IMM:
580 return LLVMInt64Type ();
581 case OP_LOADR4_MEMBASE:
582 case OP_STORER4_MEMBASE_REG:
584 return LLVMFloatType ();
585 case OP_LOADR8_MEMBASE:
586 case OP_STORER8_MEMBASE_REG:
588 return LLVMDoubleType ();
589 case OP_LOAD_MEMBASE:
591 case OP_STORE_MEMBASE_REG:
592 case OP_STORE_MEMBASE_IMM:
593 *size = sizeof (gpointer);
594 return IntPtrType ();
596 g_assert_not_reached ();
604 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
607 ovf_op_to_intrins (int opcode)
611 return "llvm.sadd.with.overflow.i32";
613 return "llvm.uadd.with.overflow.i32";
615 return "llvm.ssub.with.overflow.i32";
617 return "llvm.usub.with.overflow.i32";
619 return "llvm.smul.with.overflow.i32";
621 return "llvm.umul.with.overflow.i32";
623 return "llvm.sadd.with.overflow.i64";
625 return "llvm.uadd.with.overflow.i64";
627 return "llvm.ssub.with.overflow.i64";
629 return "llvm.usub.with.overflow.i64";
631 return "llvm.smul.with.overflow.i64";
633 return "llvm.umul.with.overflow.i64";
635 g_assert_not_reached ();
641 simd_op_to_intrins (int opcode)
644 #if defined(TARGET_X86) || defined(TARGET_AMD64)
646 return "llvm.x86.sse2.min.pd";
648 return "llvm.x86.sse.min.ps";
650 return "llvm.x86.sse41.pminud";
652 return "llvm.x86.sse41.pminuw";
654 return "llvm.x86.sse2.pminu.b";
656 return "llvm.x86.sse2.pmins.w";
658 return "llvm.x86.sse2.max.pd";
660 return "llvm.x86.sse.max.ps";
662 return "llvm.x86.sse3.hadd.pd";
664 return "llvm.x86.sse3.hadd.ps";
666 return "llvm.x86.sse3.hsub.pd";
668 return "llvm.x86.sse3.hsub.ps";
670 return "llvm.x86.sse41.pmaxud";
672 return "llvm.x86.sse41.pmaxuw";
674 return "llvm.x86.sse2.pmaxu.b";
676 return "llvm.x86.sse3.addsub.ps";
678 return "llvm.x86.sse3.addsub.pd";
679 case OP_EXTRACT_MASK:
680 return "llvm.x86.sse2.pmovmskb.128";
683 return "llvm.x86.sse2.psrli.w";
686 return "llvm.x86.sse2.psrli.d";
689 return "llvm.x86.sse2.psrli.q";
692 return "llvm.x86.sse2.pslli.w";
695 return "llvm.x86.sse2.pslli.d";
698 return "llvm.x86.sse2.pslli.q";
701 return "llvm.x86.sse2.psrai.w";
704 return "llvm.x86.sse2.psrai.d";
706 return "llvm.x86.sse2.padds.b";
708 return "llvm.x86.sse2.padds.w";
710 return "llvm.x86.sse2.psubs.b";
712 return "llvm.x86.sse2.psubs.w";
713 case OP_PADDB_SAT_UN:
714 return "llvm.x86.sse2.paddus.b";
715 case OP_PADDW_SAT_UN:
716 return "llvm.x86.sse2.paddus.w";
717 case OP_PSUBB_SAT_UN:
718 return "llvm.x86.sse2.psubus.b";
719 case OP_PSUBW_SAT_UN:
720 return "llvm.x86.sse2.psubus.w";
722 return "llvm.x86.sse2.pavg.b";
724 return "llvm.x86.sse2.pavg.w";
726 return "llvm.x86.sse.sqrt.ps";
728 return "llvm.x86.sse2.sqrt.pd";
730 return "llvm.x86.sse.rsqrt.ps";
732 return "llvm.x86.sse.rcp.ps";
734 return "llvm.x86.sse2.cvtdq2pd";
736 return "llvm.x86.sse2.cvtdq2ps";
738 return "llvm.x86.sse2.cvtpd2dq";
740 return "llvm.x86.sse2.cvtps2dq";
742 return "llvm.x86.sse2.cvtpd2ps";
744 return "llvm.x86.sse2.cvtps2pd";
746 return "llvm.x86.sse2.cvttpd2dq";
748 return "llvm.x86.sse2.cvttps2dq";
750 return "llvm.x86.sse.cmp.ps";
752 return "llvm.x86.sse2.cmp.pd";
754 return "llvm.x86.sse2.packsswb.128";
756 return "llvm.x86.sse2.packssdw.128";
758 return "llvm.x86.sse2.packuswb.128";
760 return "llvm.x86.sse41.packusdw";
762 return "llvm.x86.sse2.pmulh.w";
763 case OP_PMULW_HIGH_UN:
764 return "llvm.x86.sse2.pmulhu.w";
767 g_assert_not_reached ();
773 simd_op_to_llvm_type (int opcode)
775 #if defined(TARGET_X86) || defined(TARGET_AMD64)
779 return type_to_simd_type (MONO_TYPE_R8);
782 return type_to_simd_type (MONO_TYPE_I8);
785 return type_to_simd_type (MONO_TYPE_I4);
790 return type_to_simd_type (MONO_TYPE_I2);
794 return type_to_simd_type (MONO_TYPE_I1);
796 return type_to_simd_type (MONO_TYPE_R4);
799 return type_to_simd_type (MONO_TYPE_I4);
803 return type_to_simd_type (MONO_TYPE_R8);
807 return type_to_simd_type (MONO_TYPE_R4);
808 case OP_EXTRACT_MASK:
809 return type_to_simd_type (MONO_TYPE_I1);
815 return type_to_simd_type (MONO_TYPE_R4);
818 return type_to_simd_type (MONO_TYPE_R8);
820 g_assert_not_reached ();
831 * Return the LLVM basic block corresponding to BB.
833 static LLVMBasicBlockRef
834 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
838 if (ctx->bblocks [bb->block_num].bblock == NULL) {
839 if (bb->flags & BB_EXCEPTION_HANDLER) {
840 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
841 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
843 sprintf (bb_name, "BB%d", bb->block_num);
846 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
847 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
850 return ctx->bblocks [bb->block_num].bblock;
856 * Return the last LLVM bblock corresponding to BB.
857 * This might not be equal to the bb returned by get_bb () since we need to generate
858 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
860 static LLVMBasicBlockRef
861 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
864 return ctx->bblocks [bb->block_num].end_bblock;
867 static LLVMBasicBlockRef
868 gen_bb (EmitContext *ctx, const char *prefix)
872 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
873 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
879 * Return the target of the patch identified by TYPE and TARGET.
882 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
886 memset (&ji, 0, sizeof (ji));
888 ji.data.target = target;
890 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
896 * Emit code to convert the LLVM value V to DTYPE.
899 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
901 LLVMTypeRef stype = LLVMTypeOf (v);
903 if (stype != dtype) {
904 gboolean ext = FALSE;
907 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
909 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
911 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
915 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
917 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
918 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
921 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
922 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
923 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
924 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
925 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
926 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
927 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
928 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
930 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
931 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
932 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
933 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
934 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
935 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
937 if (mono_arch_is_soft_float ()) {
938 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
939 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
940 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
941 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
944 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
945 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
948 LLVMDumpValue (LLVMConstNull (dtype));
949 g_assert_not_reached ();
957 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
959 return convert_full (ctx, v, dtype, FALSE);
963 * emit_volatile_load:
965 * If vreg is volatile, emit a load from its address.
968 emit_volatile_load (EmitContext *ctx, int vreg)
972 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
973 t = ctx->vreg_cli_types [vreg];
974 if (t && !t->byref) {
976 * Might have to zero extend since llvm doesn't have
979 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
980 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
981 else if (t->type == MONO_TYPE_U8)
982 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
989 * emit_volatile_store:
991 * If VREG is volatile, emit a store from its value to its address.
994 emit_volatile_store (EmitContext *ctx, int vreg)
996 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
998 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
999 g_assert (ctx->addresses [vreg]);
1000 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1006 * Maps parameter indexes in the original signature to parameter indexes
1007 * in the LLVM signature.
1010 /* The indexes of various special arguments in the LLVM signature */
1011 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1015 * sig_to_llvm_sig_full:
1017 * Return the LLVM signature corresponding to the mono signature SIG using the
1018 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1021 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1024 LLVMTypeRef ret_type;
1025 LLVMTypeRef *param_types = NULL;
1027 int i, j, pindex, vret_arg_pindex = 0;
1029 gboolean vretaddr = FALSE;
1032 memset (sinfo, 0, sizeof (LLVMSigInfo));
1034 ret_type = type_to_llvm_type (ctx, sig->ret);
1035 CHECK_FAILURE (ctx);
1037 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1038 /* LLVM models this by returning an aggregate value */
1039 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1040 LLVMTypeRef members [2];
1042 members [0] = IntPtrType ();
1043 ret_type = LLVMStructType (members, 1, FALSE);
1045 g_assert_not_reached ();
1047 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1048 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1050 ret_type = LLVMVoidType ();
1053 pindexes = g_new0 (int, sig->param_count);
1054 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1056 if (cinfo && cinfo->rgctx_arg) {
1058 sinfo->rgctx_arg_pindex = pindex;
1059 param_types [pindex] = IntPtrType ();
1062 if (cinfo && cinfo->imt_arg) {
1064 sinfo->imt_arg_pindex = pindex;
1065 param_types [pindex] = IntPtrType ();
1069 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1070 vret_arg_pindex = pindex;
1071 if (cinfo->vret_arg_index == 1) {
1072 /* Add the slots consumed by the first argument */
1073 LLVMArgInfo *ainfo = &cinfo->args [0];
1074 switch (ainfo->storage) {
1075 case LLVMArgVtypeInReg:
1076 for (j = 0; j < 2; ++j) {
1077 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1087 sinfo->vret_arg_pindex = vret_arg_pindex;
1090 if (vretaddr && vret_arg_pindex == pindex)
1091 param_types [pindex ++] = IntPtrType ();
1094 sinfo->this_arg_pindex = pindex;
1095 param_types [pindex ++] = IntPtrType ();
1097 if (vretaddr && vret_arg_pindex == pindex)
1098 param_types [pindex ++] = IntPtrType ();
1099 for (i = 0; i < sig->param_count; ++i) {
1100 if (vretaddr && vret_arg_pindex == pindex)
1101 param_types [pindex ++] = IntPtrType ();
1102 pindexes [i] = pindex;
1103 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1104 for (j = 0; j < 2; ++j) {
1105 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1107 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1112 g_assert_not_reached ();
1115 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1116 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1117 CHECK_FAILURE (ctx);
1118 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1121 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1124 if (vretaddr && vret_arg_pindex == pindex)
1125 param_types [pindex ++] = IntPtrType ();
1127 CHECK_FAILURE (ctx);
1129 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1130 g_free (param_types);
1133 sinfo->pindexes = pindexes;
1141 g_free (param_types);
1147 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1149 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1153 * LLVMFunctionType1:
1155 * Create an LLVM function type from the arguments.
1157 static G_GNUC_UNUSED LLVMTypeRef
1158 LLVMFunctionType1(LLVMTypeRef ReturnType,
1159 LLVMTypeRef ParamType1,
1162 LLVMTypeRef param_types [1];
1164 param_types [0] = ParamType1;
1166 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1170 * LLVMFunctionType2:
1172 * Create an LLVM function type from the arguments.
1174 static G_GNUC_UNUSED LLVMTypeRef
1175 LLVMFunctionType2(LLVMTypeRef ReturnType,
1176 LLVMTypeRef ParamType1,
1177 LLVMTypeRef ParamType2,
1180 LLVMTypeRef param_types [2];
1182 param_types [0] = ParamType1;
1183 param_types [1] = ParamType2;
1185 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1189 * LLVMFunctionType3:
1191 * Create an LLVM function type from the arguments.
1193 static G_GNUC_UNUSED LLVMTypeRef
1194 LLVMFunctionType3(LLVMTypeRef ReturnType,
1195 LLVMTypeRef ParamType1,
1196 LLVMTypeRef ParamType2,
1197 LLVMTypeRef ParamType3,
1200 LLVMTypeRef param_types [3];
1202 param_types [0] = ParamType1;
1203 param_types [1] = ParamType2;
1204 param_types [2] = ParamType3;
1206 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1212 * Create an LLVM builder and remember it so it can be freed later.
1214 static LLVMBuilderRef
1215 create_builder (EmitContext *ctx)
1217 LLVMBuilderRef builder = LLVMCreateBuilder ();
1219 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1225 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1227 char *callee_name = mono_aot_get_plt_symbol (type, data);
1228 LLVMValueRef callee;
1233 if (ctx->cfg->compile_aot)
1234 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1235 mono_add_patch_info (ctx->cfg, 0, type, data);
1238 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1240 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1242 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1244 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1251 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1253 MonoMethodHeader *header = cfg->header;
1254 MonoExceptionClause *clause;
1258 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1259 return (bb->region >> 8) - 1;
1262 for (i = 0; i < header->num_clauses; ++i) {
1263 clause = &header->clauses [i];
1265 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1273 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1275 LLVMValueRef md_arg;
1278 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1279 md_arg = LLVMMDString ("mono", 4);
1280 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1286 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1290 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1292 MonoCompile *cfg = ctx->cfg;
1294 LLVMBuilderRef builder = *builder_ref;
1297 clause_index = get_handler_clause (cfg, bb);
1299 if (clause_index != -1) {
1300 MonoMethodHeader *header = cfg->header;
1301 MonoExceptionClause *ec = &header->clauses [clause_index];
1302 MonoBasicBlock *tblock;
1303 LLVMBasicBlockRef ex_bb, noex_bb;
1306 * Have to use an invoke instead of a call, branching to the
1307 * handler bblock of the clause containing this bblock.
1310 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1312 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1315 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1317 ex_bb = get_bb (ctx, tblock);
1319 noex_bb = gen_bb (ctx, "NOEX_BB");
1322 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1324 builder = ctx->builder = create_builder (ctx);
1325 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1327 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1329 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1330 ctx->builder = builder;
1333 *builder_ref = ctx->builder;
1339 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1341 const char *intrins_name;
1342 LLVMValueRef args [16], res;
1343 LLVMTypeRef addr_type;
1345 if (is_faulting && bb->region != -1) {
1347 * We handle loads which can fault by calling a mono specific intrinsic
1348 * using an invoke, so they are handled properly inside try blocks.
1349 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1350 * are marked with IntrReadArgMem.
1354 intrins_name = "llvm.mono.load.i8.p0i8";
1357 intrins_name = "llvm.mono.load.i16.p0i16";
1360 intrins_name = "llvm.mono.load.i32.p0i32";
1363 intrins_name = "llvm.mono.load.i64.p0i64";
1366 g_assert_not_reached ();
1369 addr_type = LLVMTypeOf (addr);
1370 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1371 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1374 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1375 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1376 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1378 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1379 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1380 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1381 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1388 * We emit volatile loads for loads which can fault, because otherwise
1389 * LLVM will generate invalid code when encountering a load from a
1392 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1394 /* Mark it with a custom metadata */
1397 set_metadata_flag (res, "mono.faulting.load");
1405 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1407 const char *intrins_name;
1408 LLVMValueRef args [16];
1410 if (is_faulting && bb->region != -1) {
1413 intrins_name = "llvm.mono.store.i8.p0i8";
1416 intrins_name = "llvm.mono.store.i16.p0i16";
1419 intrins_name = "llvm.mono.store.i32.p0i32";
1422 intrins_name = "llvm.mono.store.i64.p0i64";
1425 g_assert_not_reached ();
1428 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1429 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1430 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1435 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1436 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1437 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1439 LLVMBuildStore (*builder_ref, value, addr);
1444 * emit_cond_system_exception:
1446 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1447 * Might set the ctx exception.
1450 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1452 LLVMBasicBlockRef ex_bb, noex_bb;
1453 LLVMBuilderRef builder;
1454 MonoClass *exc_class;
1455 LLVMValueRef args [2];
1457 ex_bb = gen_bb (ctx, "EX_BB");
1458 noex_bb = gen_bb (ctx, "NOEX_BB");
1460 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1462 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1463 g_assert (exc_class);
1465 /* Emit exception throwing code */
1466 builder = create_builder (ctx);
1467 LLVMPositionBuilderAtEnd (builder, ex_bb);
1469 if (!ctx->lmodule->throw_corlib_exception) {
1470 LLVMValueRef callee;
1472 const char *icall_name;
1474 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1475 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1476 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1477 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1478 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1479 sig = sig_to_llvm_sig (ctx, throw_sig);
1481 if (ctx->cfg->compile_aot) {
1482 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1484 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1487 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1488 * - On x86, LLVM generated code doesn't push the arguments
1489 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1490 * arguments, not a pc offset.
1492 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1495 mono_memory_barrier ();
1496 ctx->lmodule->throw_corlib_exception = callee;
1500 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1502 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1505 * The LLVM mono branch contains changes so a block address can be passed as an
1506 * argument to a call.
1508 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1509 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1511 LLVMBuildUnreachable (builder);
1513 ctx->builder = create_builder (ctx);
1514 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1516 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1523 * emit_reg_to_vtype:
1525 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1528 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1532 size = get_vtype_size (t);
1534 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1535 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1538 for (j = 0; j < 2; ++j) {
1539 LLVMValueRef index [2], addr;
1540 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1541 LLVMTypeRef part_type;
1543 if (ainfo->pair_storage [j] == LLVMArgNone)
1546 part_type = LLVMIntType (part_size * 8);
1547 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1548 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1549 addr = LLVMBuildGEP (builder, address, index, 1, "");
1551 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1552 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1553 addr = LLVMBuildGEP (builder, address, index, 2, "");
1555 switch (ainfo->pair_storage [j]) {
1557 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1562 g_assert_not_reached ();
1565 size -= sizeof (gpointer);
1570 * emit_vtype_to_reg:
1572 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1573 * into REGS, and the number of registers into NREGS.
1576 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1581 size = get_vtype_size (t);
1583 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1584 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1587 for (j = 0; j < 2; ++j) {
1588 LLVMValueRef index [2], addr;
1589 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1591 if (ainfo->pair_storage [j] == LLVMArgNone)
1594 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1595 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1596 addr = LLVMBuildGEP (builder, address, index, 1, "");
1598 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1599 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1600 addr = LLVMBuildGEP (builder, address, index, 2, "");
1602 switch (ainfo->pair_storage [j]) {
1604 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1609 g_assert_not_reached ();
1611 size -= sizeof (gpointer);
1618 build_alloca (EmitContext *ctx, MonoType *t)
1620 MonoClass *k = mono_class_from_mono_type (t);
1623 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1626 align = mono_class_min_align (k);
1628 /* Sometimes align is not a power of 2 */
1629 while (mono_is_power_of_two (align) == -1)
1633 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1634 * get executed every time control reaches them.
1636 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1638 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1639 return ctx->last_alloca;
1643 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1646 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1648 LLVMTypeRef used_type;
1649 LLVMValueRef used, used_elem;
1651 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1652 used = LLVMAddGlobal (module, used_type, "llvm.used");
1653 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1654 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1655 LLVMSetLinkage (used, LLVMAppendingLinkage);
1656 LLVMSetSection (used, "llvm.metadata");
1662 * Emit code to load/convert arguments.
1665 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1668 MonoCompile *cfg = ctx->cfg;
1669 MonoMethodSignature *sig = ctx->sig;
1670 LLVMCallInfo *linfo = ctx->linfo;
1673 ctx->alloca_builder = create_builder (ctx);
1676 * Handle indirect/volatile variables by allocating memory for them
1677 * using 'alloca', and storing their address in a temporary.
1679 for (i = 0; i < cfg->num_varinfo; ++i) {
1680 MonoInst *var = cfg->varinfo [i];
1683 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1684 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1685 CHECK_FAILURE (ctx);
1686 /* Could be already created by an OP_VPHI */
1687 if (!ctx->addresses [var->dreg])
1688 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1689 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1693 for (i = 0; i < sig->param_count; ++i) {
1694 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1695 int reg = cfg->args [i + sig->hasthis]->dreg;
1697 if (ainfo->storage == LLVMArgVtypeInReg) {
1698 LLVMValueRef regs [2];
1701 * Emit code to save the argument from the registers to
1702 * the real argument.
1704 pindex = ctx->pindexes [i];
1705 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1706 if (ainfo->pair_storage [1] != LLVMArgNone)
1707 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1711 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1713 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1715 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1716 /* Treat these as normal values */
1717 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1719 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1720 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1722 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1723 /* Treat these as normal values */
1724 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1727 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1732 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1734 emit_volatile_store (ctx, cfg->args [0]->dreg);
1735 for (i = 0; i < sig->param_count; ++i)
1736 if (!mini_type_is_vtype (cfg, sig->params [i]))
1737 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1739 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1740 LLVMValueRef this_alloc;
1743 * The exception handling code needs the location where the this argument was
1744 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1745 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1746 * location into the LSDA.
1748 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1749 /* This volatile store will keep the alloca alive */
1750 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1752 set_metadata_flag (this_alloc, "mono.this");
1755 if (cfg->rgctx_var) {
1756 LLVMValueRef rgctx_alloc, store;
1759 * We handle the rgctx arg similarly to the this pointer.
1761 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1762 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1763 /* This volatile store will keep the alloca alive */
1764 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1766 set_metadata_flag (rgctx_alloc, "mono.this");
1770 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1771 * it needs to continue normally, or return back to the exception handling system.
1773 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1774 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1775 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1776 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1780 sprintf (name, "finally_ind_bb%d", bb->block_num);
1781 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1782 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1784 ctx->bblocks [bb->block_num].finally_ind = val;
1787 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1788 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1789 * LLVM optimizer passes.
1791 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1792 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1800 /* Have to export this for AOT */
1802 mono_personality (void);
1805 mono_personality (void)
1808 g_assert_not_reached ();
1812 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1814 MonoCompile *cfg = ctx->cfg;
1815 LLVMModuleRef module = ctx->module;
1816 LLVMValueRef *values = ctx->values;
1817 LLVMValueRef *addresses = ctx->addresses;
1818 MonoCallInst *call = (MonoCallInst*)ins;
1819 MonoMethodSignature *sig = call->signature;
1820 LLVMValueRef callee = NULL, lcall;
1822 LLVMCallInfo *cinfo;
1826 LLVMTypeRef llvm_sig;
1828 gboolean virtual, calli;
1829 LLVMBuilderRef builder = *builder_ref;
1832 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1833 LLVM_FAILURE (ctx, "non-default callconv");
1835 cinfo = call->cinfo;
1836 if (call->rgctx_arg_reg)
1837 cinfo->rgctx_arg = TRUE;
1838 if (call->imt_arg_reg)
1839 cinfo->imt_arg = TRUE;
1841 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1843 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1844 CHECK_FAILURE (ctx);
1846 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);
1847 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);
1849 /* FIXME: Avoid creating duplicate methods */
1851 if (ins->flags & MONO_INST_HAS_METHOD) {
1855 if (cfg->compile_aot) {
1856 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1858 LLVM_FAILURE (ctx, "can't encode patch");
1860 callee = LLVMAddFunction (module, "", llvm_sig);
1863 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1865 LLVMAddGlobalMapping (ee, callee, target);
1869 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1870 /* LLVM miscompiles async methods */
1871 LLVM_FAILURE (ctx, "#13734");
1874 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1880 memset (&ji, 0, sizeof (ji));
1881 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1882 ji.data.target = info->name;
1884 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1886 if (cfg->compile_aot) {
1887 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1889 LLVM_FAILURE (ctx, "can't encode patch");
1891 callee = LLVMAddFunction (module, "", llvm_sig);
1892 target = (gpointer)mono_icall_get_wrapper (info);
1893 LLVMAddGlobalMapping (ee, callee, target);
1896 if (cfg->compile_aot) {
1898 if (cfg->abs_patches) {
1899 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1901 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1903 LLVM_FAILURE (ctx, "can't encode patch");
1907 LLVM_FAILURE (ctx, "aot");
1909 callee = LLVMAddFunction (module, "", llvm_sig);
1911 if (cfg->abs_patches) {
1912 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1915 * FIXME: Some trampolines might have
1916 * their own calling convention on some platforms.
1918 #ifndef TARGET_AMD64
1919 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)
1920 LLVM_FAILURE (ctx, "trampoline with own cconv");
1922 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1923 LLVMAddGlobalMapping (ee, callee, target);
1927 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1933 int size = sizeof (gpointer);
1936 g_assert (ins->inst_offset % size == 0);
1937 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1939 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1941 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1943 if (ins->flags & MONO_INST_HAS_METHOD) {
1948 * Collect and convert arguments
1950 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
1951 len = sizeof (LLVMValueRef) * nargs;
1952 args = alloca (len);
1953 memset (args, 0, len);
1954 l = call->out_ireg_args;
1956 if (call->rgctx_arg_reg) {
1957 g_assert (values [call->rgctx_arg_reg]);
1958 g_assert (sinfo.rgctx_arg_pindex < nargs);
1959 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1961 if (call->imt_arg_reg) {
1962 g_assert (values [call->imt_arg_reg]);
1963 g_assert (sinfo.imt_arg_pindex < nargs);
1964 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1968 if (!addresses [call->inst.dreg])
1969 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1970 g_assert (sinfo.vret_arg_pindex < nargs);
1971 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1974 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1977 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1981 pindex = sinfo.this_arg_pindex;
1983 pindex = sinfo.pindexes [i - 1];
1985 pindex = sinfo.pindexes [i];
1988 regpair = (guint32)(gssize)(l->data);
1989 reg = regpair & 0xffffff;
1990 args [pindex] = values [reg];
1991 if (ainfo->storage == LLVMArgVtypeInReg) {
1993 LLVMValueRef regs [2];
1998 g_assert (addresses [reg]);
2000 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2001 for (j = 0; j < nregs; ++j)
2002 args [pindex ++] = regs [j];
2005 // FIXME: Get rid of the VMOVE
2006 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2007 g_assert (addresses [reg]);
2008 args [pindex] = addresses [reg];
2010 g_assert (args [pindex]);
2011 if (i == 0 && sig->hasthis)
2012 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2014 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2020 // FIXME: Align call sites
2026 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2028 #ifdef LLVM_MONO_BRANCH
2030 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2032 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2033 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2035 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2036 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2038 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2040 if (call->rgctx_arg_reg)
2041 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2042 if (call->imt_arg_reg)
2043 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2046 /* Add byval attributes if needed */
2047 for (i = 0; i < sig->param_count; ++i) {
2048 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2050 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2051 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2056 * Convert the result
2058 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2059 LLVMValueRef regs [2];
2061 if (!addresses [ins->dreg])
2062 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2064 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2065 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2066 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2068 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2069 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2070 /* If the method returns an unsigned value, need to zext it */
2072 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));
2075 *builder_ref = ctx->builder;
2077 g_free (sinfo.pindexes);
2085 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2087 MonoCompile *cfg = ctx->cfg;
2088 MonoMethodSignature *sig = ctx->sig;
2089 LLVMValueRef method = ctx->lmethod;
2090 LLVMValueRef *values = ctx->values;
2091 LLVMValueRef *addresses = ctx->addresses;
2093 LLVMCallInfo *linfo = ctx->linfo;
2094 LLVMModuleRef module = ctx->module;
2095 BBInfo *bblocks = ctx->bblocks;
2097 LLVMBasicBlockRef cbb;
2098 LLVMBuilderRef builder, starting_builder;
2099 gboolean has_terminator;
2101 LLVMValueRef lhs, rhs;
2104 cbb = get_bb (ctx, bb);
2105 builder = create_builder (ctx);
2106 ctx->builder = builder;
2107 LLVMPositionBuilderAtEnd (builder, cbb);
2109 if (bb == cfg->bb_entry)
2110 emit_entry_bb (ctx, builder);
2111 CHECK_FAILURE (ctx);
2113 if (bb->flags & BB_EXCEPTION_HANDLER) {
2115 LLVMValueRef personality;
2116 LLVMBasicBlockRef target_bb;
2118 static gint32 mapping_inited;
2119 static int ti_generator;
2122 LLVMValueRef type_info;
2125 if (!bblocks [bb->block_num].invoke_target) {
2127 * LLVM asserts if llvm.eh.selector is called from a bblock which
2128 * doesn't have an invoke pointing at it.
2129 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2131 LLVM_FAILURE (ctx, "handler without invokes");
2134 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2136 if (cfg->compile_aot) {
2137 /* Use a dummy personality function */
2138 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2139 g_assert (personality);
2141 personality = LLVMGetNamedFunction (module, "mono_personality");
2142 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2143 LLVMAddGlobalMapping (ee, personality, mono_personality);
2146 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2148 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2151 * Create the type info
2153 sprintf (ti_name, "type_info_%d", ti_generator);
2156 if (cfg->compile_aot) {
2157 /* decode_eh_frame () in aot-runtime.c will decode this */
2158 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2159 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2162 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2164 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2167 * Enabling this causes llc to crash:
2168 * http://llvm.org/bugs/show_bug.cgi?id=6102
2170 //LLVM_FAILURE (ctx, "aot+clauses");
2172 // test_0_invalid_unbox_arrays () fails
2173 LLVM_FAILURE (ctx, "aot+clauses");
2177 * After the cfg mempool is freed, the type info will point to stale memory,
2178 * but this is not a problem, since we decode it once in exception_cb during
2181 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2182 *(gint32*)ti = clause_index;
2184 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2186 LLVMAddGlobalMapping (ee, type_info, ti);
2190 LLVMTypeRef members [2], ret_type;
2191 LLVMValueRef landing_pad;
2193 members [0] = i8ptr;
2194 members [1] = LLVMInt32Type ();
2195 ret_type = LLVMStructType (members, 2, FALSE);
2197 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2198 LLVMAddClause (landing_pad, type_info);
2200 /* Store the exception into the exvar */
2201 if (bb->in_scount == 1) {
2202 g_assert (bb->in_scount == 1);
2203 exvar = bb->in_stack [0];
2205 // FIXME: This is shared with filter clauses ?
2206 g_assert (!values [exvar->dreg]);
2208 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2209 emit_volatile_store (ctx, exvar->dreg);
2213 /* Start a new bblock which CALL_HANDLER can branch to */
2214 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2216 LLVMBuildBr (builder, target_bb);
2218 ctx->builder = builder = create_builder (ctx);
2219 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2221 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2225 has_terminator = FALSE;
2226 starting_builder = builder;
2227 for (ins = bb->code; ins; ins = ins->next) {
2228 const char *spec = LLVM_INS_INFO (ins->opcode);
2230 char dname_buf [128];
2233 if (nins > 5000 && builder == starting_builder) {
2234 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2235 LLVM_FAILURE (ctx, "basic block too long");
2239 /* There could be instructions after a terminator, skip them */
2242 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2243 sprintf (dname_buf, "t%d", ins->dreg);
2247 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2248 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2250 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2251 lhs = emit_volatile_load (ctx, ins->sreg1);
2253 /* It is ok for SETRET to have an uninitialized argument */
2254 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2255 LLVM_FAILURE (ctx, "sreg1");
2256 lhs = values [ins->sreg1];
2262 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2263 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2264 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2265 rhs = emit_volatile_load (ctx, ins->sreg2);
2267 if (!values [ins->sreg2])
2268 LLVM_FAILURE (ctx, "sreg2");
2269 rhs = values [ins->sreg2];
2275 //mono_print_ins (ins);
2276 switch (ins->opcode) {
2279 case OP_LIVERANGE_START:
2280 case OP_LIVERANGE_END:
2283 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2286 #if SIZEOF_VOID_P == 4
2287 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2289 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2293 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2296 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2299 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2300 has_terminator = TRUE;
2306 LLVMBasicBlockRef new_bb;
2307 LLVMBuilderRef new_builder;
2309 // The default branch is already handled
2310 // FIXME: Handle it here
2312 /* Start new bblock */
2313 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2314 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2316 lhs = convert (ctx, lhs, LLVMInt32Type ());
2317 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2318 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2319 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2321 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2324 new_builder = create_builder (ctx);
2325 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2326 LLVMBuildUnreachable (new_builder);
2328 has_terminator = TRUE;
2329 g_assert (!ins->next);
2335 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2336 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2337 LLVMValueRef part1, retval;
2340 size = get_vtype_size (sig->ret);
2342 g_assert (addresses [ins->sreg1]);
2344 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2345 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2347 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2349 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2351 LLVMBuildRet (builder, retval);
2355 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2356 LLVMBuildRetVoid (builder);
2360 if (!lhs || ctx->is_dead [ins->sreg1]) {
2362 * The method did not set its return value, probably because it
2363 * ends with a throw.
2366 LLVMBuildRetVoid (builder);
2368 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2370 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2372 has_terminator = TRUE;
2378 case OP_ICOMPARE_IMM:
2379 case OP_LCOMPARE_IMM:
2380 case OP_COMPARE_IMM: {
2384 if (ins->next->opcode == OP_NOP)
2387 if (ins->next->opcode == OP_BR)
2388 /* The comparison result is not needed */
2391 rel = mono_opcode_to_cond (ins->next->opcode);
2393 if (ins->opcode == OP_ICOMPARE_IMM) {
2394 lhs = convert (ctx, lhs, LLVMInt32Type ());
2395 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2397 if (ins->opcode == OP_LCOMPARE_IMM) {
2398 lhs = convert (ctx, lhs, LLVMInt64Type ());
2399 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2401 if (ins->opcode == OP_LCOMPARE) {
2402 lhs = convert (ctx, lhs, LLVMInt64Type ());
2403 rhs = convert (ctx, rhs, LLVMInt64Type ());
2405 if (ins->opcode == OP_ICOMPARE) {
2406 lhs = convert (ctx, lhs, LLVMInt32Type ());
2407 rhs = convert (ctx, rhs, LLVMInt32Type ());
2411 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2412 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2413 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2414 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2417 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2418 if (ins->opcode == OP_FCOMPARE)
2419 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2420 else if (ins->opcode == OP_COMPARE_IMM)
2421 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2422 else if (ins->opcode == OP_LCOMPARE_IMM) {
2423 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2424 /* The immediate is encoded in two fields */
2425 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2426 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2428 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2431 else if (ins->opcode == OP_COMPARE)
2432 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2434 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2436 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2437 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2439 * If the target bb contains PHI instructions, LLVM requires
2440 * two PHI entries for this bblock, while we only generate one.
2441 * So convert this to an unconditional bblock. (bxc #171).
2443 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2445 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2447 has_terminator = TRUE;
2448 } else if (MONO_IS_SETCC (ins->next)) {
2449 sprintf (dname_buf, "t%d", ins->next->dreg);
2451 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2453 /* Add stores for volatile variables */
2454 emit_volatile_store (ctx, ins->next->dreg);
2455 } else if (MONO_IS_COND_EXC (ins->next)) {
2456 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2457 CHECK_FAILURE (ctx);
2458 builder = ctx->builder;
2460 LLVM_FAILURE (ctx, "next");
2474 rel = mono_opcode_to_cond (ins->opcode);
2476 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2477 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2485 gboolean empty = TRUE;
2487 /* Check that all input bblocks really branch to us */
2488 for (i = 0; i < bb->in_count; ++i) {
2489 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2490 ins->inst_phi_args [i + 1] = -1;
2496 /* LLVM doesn't like phi instructions with zero operands */
2497 ctx->is_dead [ins->dreg] = TRUE;
2501 /* Created earlier, insert it now */
2502 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2504 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2505 int sreg1 = ins->inst_phi_args [i + 1];
2509 * Count the number of times the incoming bblock branches to us,
2510 * since llvm requires a separate entry for each.
2512 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2513 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2516 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2517 if (switch_ins->inst_many_bb [j] == bb)
2524 /* Remember for later */
2525 for (j = 0; j < count; ++j) {
2526 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2529 node->in_bb = bb->in_bb [i];
2531 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);
2541 values [ins->dreg] = lhs;
2544 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2547 values [ins->dreg] = lhs;
2549 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2551 * This is added by the spilling pass in case of the JIT,
2552 * but we have to do it ourselves.
2554 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2588 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2589 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2591 switch (ins->opcode) {
2594 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2598 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2602 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2606 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2610 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2614 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2618 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2621 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2625 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2629 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2633 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2637 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2641 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2645 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2649 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2652 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2655 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2659 g_assert_not_reached ();
2666 case OP_IREM_UN_IMM:
2668 case OP_IDIV_UN_IMM:
2674 case OP_ISHR_UN_IMM:
2683 case OP_LSHR_UN_IMM:
2691 if (spec [MONO_INST_SRC1] == 'l') {
2692 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2694 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2697 #if SIZEOF_VOID_P == 4
2698 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2699 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2702 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2703 lhs = convert (ctx, lhs, IntPtrType ());
2704 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2705 switch (ins->opcode) {
2709 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2713 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2717 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2721 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2723 case OP_IDIV_UN_IMM:
2724 case OP_LDIV_UN_IMM:
2725 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2729 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2731 case OP_IREM_UN_IMM:
2732 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2737 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2741 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2745 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2750 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2755 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2757 case OP_ISHR_UN_IMM:
2758 /* This is used to implement conv.u4, so the lhs could be an i8 */
2759 lhs = convert (ctx, lhs, LLVMInt32Type ());
2760 imm = convert (ctx, imm, LLVMInt32Type ());
2761 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2763 case OP_LSHR_UN_IMM:
2764 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2767 g_assert_not_reached ();
2772 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2775 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2778 lhs = convert (ctx, lhs, LLVMDoubleType ());
2779 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2782 guint32 v = 0xffffffff;
2783 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2787 guint64 v = 0xffffffffffffffffLL;
2788 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2791 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2793 LLVMValueRef v1, v2;
2795 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2796 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2797 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2802 case OP_ICONV_TO_I1:
2803 case OP_ICONV_TO_I2:
2804 case OP_ICONV_TO_I4:
2805 case OP_ICONV_TO_U1:
2806 case OP_ICONV_TO_U2:
2807 case OP_ICONV_TO_U4:
2808 case OP_LCONV_TO_I1:
2809 case OP_LCONV_TO_I2:
2810 case OP_LCONV_TO_U1:
2811 case OP_LCONV_TO_U2:
2812 case OP_LCONV_TO_U4: {
2815 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);
2817 /* Have to do two casts since our vregs have type int */
2818 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2820 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2822 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2825 case OP_ICONV_TO_I8:
2826 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2828 case OP_ICONV_TO_U8:
2829 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2831 case OP_FCONV_TO_I4:
2832 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2834 case OP_FCONV_TO_I1:
2835 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2837 case OP_FCONV_TO_U1:
2838 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2840 case OP_FCONV_TO_I2:
2841 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2843 case OP_FCONV_TO_U2:
2844 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2846 case OP_FCONV_TO_I8:
2847 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2850 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2852 case OP_ICONV_TO_R8:
2853 case OP_LCONV_TO_R8:
2854 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2856 case OP_LCONV_TO_R_UN:
2857 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2859 #if SIZEOF_VOID_P == 4
2862 case OP_LCONV_TO_I4:
2863 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2865 case OP_ICONV_TO_R4:
2866 case OP_LCONV_TO_R4:
2867 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2868 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2870 case OP_FCONV_TO_R4:
2871 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2872 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2875 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2878 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2881 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2883 case OP_LOCALLOC_IMM: {
2886 guint32 size = ins->inst_imm;
2887 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2889 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2891 if (ins->flags & MONO_INST_INIT) {
2892 LLVMValueRef args [5];
2895 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2896 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2897 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2898 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2899 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2902 values [ins->dreg] = v;
2906 LLVMValueRef v, size;
2908 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), "");
2910 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2912 if (ins->flags & MONO_INST_INIT) {
2913 LLVMValueRef args [5];
2916 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2918 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2919 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2920 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2922 values [ins->dreg] = v;
2926 case OP_LOADI1_MEMBASE:
2927 case OP_LOADU1_MEMBASE:
2928 case OP_LOADI2_MEMBASE:
2929 case OP_LOADU2_MEMBASE:
2930 case OP_LOADI4_MEMBASE:
2931 case OP_LOADU4_MEMBASE:
2932 case OP_LOADI8_MEMBASE:
2933 case OP_LOADR4_MEMBASE:
2934 case OP_LOADR8_MEMBASE:
2935 case OP_LOAD_MEMBASE:
2943 LLVMValueRef base, index, addr;
2945 gboolean sext = FALSE, zext = FALSE;
2946 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2948 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2953 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)) {
2954 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2959 if (ins->inst_offset == 0) {
2961 } else if (ins->inst_offset % size != 0) {
2962 /* Unaligned load */
2963 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2964 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2966 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2967 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2971 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2973 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2975 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2977 * These will signal LLVM that these loads do not alias any stores, and
2978 * they can't fail, allowing them to be hoisted out of loops.
2980 set_metadata_flag (values [ins->dreg], "mono.noalias");
2981 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2985 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2987 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2988 else if (ins->opcode == OP_LOADR4_MEMBASE)
2989 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2993 case OP_STOREI1_MEMBASE_REG:
2994 case OP_STOREI2_MEMBASE_REG:
2995 case OP_STOREI4_MEMBASE_REG:
2996 case OP_STOREI8_MEMBASE_REG:
2997 case OP_STORER4_MEMBASE_REG:
2998 case OP_STORER8_MEMBASE_REG:
2999 case OP_STORE_MEMBASE_REG: {
3001 LLVMValueRef index, addr;
3003 gboolean sext = FALSE, zext = FALSE;
3004 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3006 if (!values [ins->inst_destbasereg])
3007 LLVM_FAILURE (ctx, "inst_destbasereg");
3009 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3011 if (ins->inst_offset % size != 0) {
3012 /* Unaligned store */
3013 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3014 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3016 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3017 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3019 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3023 case OP_STOREI1_MEMBASE_IMM:
3024 case OP_STOREI2_MEMBASE_IMM:
3025 case OP_STOREI4_MEMBASE_IMM:
3026 case OP_STOREI8_MEMBASE_IMM:
3027 case OP_STORE_MEMBASE_IMM: {
3029 LLVMValueRef index, addr;
3031 gboolean sext = FALSE, zext = FALSE;
3032 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3034 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3036 if (ins->inst_offset % size != 0) {
3037 /* Unaligned store */
3038 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3039 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3041 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3042 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3044 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3049 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3051 case OP_OUTARG_VTRETADDR:
3058 case OP_VOIDCALL_MEMBASE:
3059 case OP_CALL_MEMBASE:
3060 case OP_LCALL_MEMBASE:
3061 case OP_FCALL_MEMBASE:
3062 case OP_VCALL_MEMBASE:
3063 case OP_VOIDCALL_REG:
3067 case OP_VCALL_REG: {
3068 process_call (ctx, bb, &builder, ins);
3069 CHECK_FAILURE (ctx);
3074 LLVMValueRef indexes [2];
3076 LLVMValueRef got_entry_addr;
3079 * FIXME: Can't allocate from the cfg mempool since that is freed if
3080 * the LLVM compile fails.
3082 ji = g_new0 (MonoJumpInfo, 1);
3083 ji->type = (MonoJumpInfoType)ins->inst_i1;
3084 ji->data.target = ins->inst_p0;
3086 ji = mono_aot_patch_info_dup (ji);
3088 ji->next = cfg->patch_info;
3089 cfg->patch_info = ji;
3091 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3092 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3094 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3095 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3096 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3098 // FIXME: This doesn't work right now, because it must be
3099 // paired with an invariant.end, and even then, its only in effect
3100 // inside its basic block
3103 LLVMValueRef args [3];
3104 LLVMValueRef ptr, val;
3106 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3108 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3110 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3114 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3117 case OP_NOT_REACHED:
3118 LLVMBuildUnreachable (builder);
3119 has_terminator = TRUE;
3120 g_assert (bb->block_num < cfg->max_block_num);
3121 ctx->unreachable [bb->block_num] = TRUE;
3122 /* Might have instructions after this */
3124 MonoInst *next = ins->next;
3126 * FIXME: If later code uses the regs defined by these instructions,
3127 * compilation will fail.
3129 MONO_DELETE_INS (bb, next);
3133 MonoInst *var = ins->inst_p0;
3135 values [ins->dreg] = addresses [var->dreg];
3139 LLVMValueRef args [1];
3141 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3142 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3146 LLVMValueRef args [1];
3148 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3149 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3153 LLVMValueRef args [1];
3156 /* This no longer seems to happen */
3158 * LLVM optimizes sqrt(nan) into undefined in
3159 * lib/Analysis/ConstantFolding.cpp
3160 * Also, sqrt(NegativeInfinity) is optimized into 0.
3162 LLVM_FAILURE (ctx, "sqrt");
3164 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3165 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3169 LLVMValueRef args [1];
3171 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3172 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3186 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3187 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3189 switch (ins->opcode) {
3192 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3196 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3200 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3204 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3207 g_assert_not_reached ();
3210 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3213 case OP_ATOMIC_EXCHANGE_I4: {
3214 LLVMValueRef args [2];
3216 g_assert (ins->inst_offset == 0);
3218 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3221 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3224 case OP_ATOMIC_EXCHANGE_I8: {
3225 LLVMValueRef args [2];
3227 g_assert (ins->inst_offset == 0);
3229 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3230 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3231 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3234 case OP_ATOMIC_ADD_NEW_I4: {
3235 LLVMValueRef args [2];
3237 g_assert (ins->inst_offset == 0);
3239 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3241 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3244 case OP_ATOMIC_ADD_NEW_I8: {
3245 LLVMValueRef args [2];
3247 g_assert (ins->inst_offset == 0);
3249 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3250 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3251 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3254 case OP_ATOMIC_CAS_I4:
3255 case OP_ATOMIC_CAS_I8: {
3256 LLVMValueRef args [3];
3259 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3260 t = LLVMInt32Type ();
3262 t = LLVMInt64Type ();
3265 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3267 args [1] = convert (ctx, values [ins->sreg3], t);
3269 args [2] = convert (ctx, values [ins->sreg2], t);
3270 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3273 case OP_MEMORY_BARRIER: {
3274 mono_llvm_build_fence (builder);
3277 case OP_RELAXED_NOP: {
3278 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3279 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3286 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3288 // 257 == FS segment register
3289 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3291 // 256 == GS segment register
3292 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3296 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3298 LLVM_FAILURE (ctx, "opcode tls-get");
3308 case OP_IADD_OVF_UN:
3310 case OP_ISUB_OVF_UN:
3312 case OP_IMUL_OVF_UN:
3313 #if SIZEOF_VOID_P == 8
3315 case OP_LADD_OVF_UN:
3317 case OP_LSUB_OVF_UN:
3319 case OP_LMUL_OVF_UN:
3322 LLVMValueRef args [2], val, ovf, func;
3324 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3325 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3326 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3328 val = LLVMBuildCall (builder, func, args, 2, "");
3329 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3330 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3331 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3332 CHECK_FAILURE (ctx);
3333 builder = ctx->builder;
3339 * We currently model them using arrays. Promotion to local vregs is
3340 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3341 * so we always have an entry in cfg->varinfo for them.
3342 * FIXME: Is this needed ?
3345 MonoClass *klass = ins->klass;
3346 LLVMValueRef args [5];
3350 LLVM_FAILURE (ctx, "!klass");
3354 if (!addresses [ins->dreg])
3355 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3356 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3357 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3358 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3360 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3361 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3362 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3366 case OP_STOREV_MEMBASE:
3367 case OP_LOADV_MEMBASE:
3369 MonoClass *klass = ins->klass;
3370 LLVMValueRef src = NULL, dst, args [5];
3371 gboolean done = FALSE;
3375 LLVM_FAILURE (ctx, "!klass");
3379 if (mini_is_gsharedvt_klass (cfg, klass)) {
3381 LLVM_FAILURE (ctx, "gsharedvt");
3385 switch (ins->opcode) {
3386 case OP_STOREV_MEMBASE:
3387 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3388 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3389 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3392 if (!addresses [ins->sreg1]) {
3394 g_assert (values [ins->sreg1]);
3395 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));
3396 LLVMBuildStore (builder, values [ins->sreg1], dst);
3399 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3400 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3403 case OP_LOADV_MEMBASE:
3404 if (!addresses [ins->dreg])
3405 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3406 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3407 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3410 if (!addresses [ins->sreg1])
3411 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3412 if (!addresses [ins->dreg])
3413 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3414 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3415 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3418 g_assert_not_reached ();
3420 CHECK_FAILURE (ctx);
3427 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3428 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3430 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3431 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3432 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3435 case OP_LLVM_OUTARG_VT:
3436 if (!addresses [ins->sreg1]) {
3437 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3438 g_assert (values [ins->sreg1]);
3439 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3441 addresses [ins->dreg] = addresses [ins->sreg1];
3447 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3449 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3452 case OP_LOADX_MEMBASE: {
3453 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3456 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3457 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3460 case OP_STOREX_MEMBASE: {
3461 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3464 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3465 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3472 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3476 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3482 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3486 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3490 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3494 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3497 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3500 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3503 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3507 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3518 LLVMValueRef v = NULL;
3520 switch (ins->opcode) {
3525 t = LLVMVectorType (LLVMInt32Type (), 4);
3526 rt = LLVMVectorType (LLVMFloatType (), 4);
3532 t = LLVMVectorType (LLVMInt64Type (), 2);
3533 rt = LLVMVectorType (LLVMDoubleType (), 2);
3536 t = LLVMInt32Type ();
3537 rt = LLVMInt32Type ();
3538 g_assert_not_reached ();
3541 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3542 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3543 switch (ins->opcode) {
3546 v = LLVMBuildAnd (builder, lhs, rhs, "");
3550 v = LLVMBuildOr (builder, lhs, rhs, "");
3554 v = LLVMBuildXor (builder, lhs, rhs, "");
3558 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3561 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3585 case OP_PADDB_SAT_UN:
3586 case OP_PADDW_SAT_UN:
3587 case OP_PSUBB_SAT_UN:
3588 case OP_PSUBW_SAT_UN:
3596 case OP_PMULW_HIGH_UN: {
3597 LLVMValueRef args [2];
3602 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3609 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3613 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3621 case OP_EXTRACTX_U2:
3623 case OP_EXTRACT_U1: {
3625 gboolean zext = FALSE;
3627 t = simd_op_to_llvm_type (ins->opcode);
3629 switch (ins->opcode) {
3637 case OP_EXTRACTX_U2:
3642 t = LLVMInt32Type ();
3643 g_assert_not_reached ();
3646 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3647 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3649 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3658 case OP_EXPAND_R8: {
3659 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3660 LLVMValueRef mask [16], v;
3662 for (i = 0; i < 16; ++i)
3663 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3665 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3667 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3668 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3673 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3676 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3679 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3682 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3685 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3688 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3699 case OP_EXTRACT_MASK:
3706 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3708 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3712 case OP_ICONV_TO_R8_RAW:
3713 /* Same as OP_ICONV_TO_R8 */
3714 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3719 LLVMValueRef args [3];
3723 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3725 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3730 /* This is only used for implementing shifts by non-immediate */
3731 values [ins->dreg] = lhs;
3742 LLVMValueRef args [3];
3745 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3747 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3758 case OP_PSHLQ_REG: {
3759 LLVMValueRef args [3];
3762 args [1] = values [ins->sreg2];
3764 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3771 case OP_PSHUFLEW_LOW:
3772 case OP_PSHUFLEW_HIGH: {
3774 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3775 int i, mask_size = 0;
3776 int imask = ins->inst_c0;
3778 /* Convert the x86 shuffle mask to LLVM's */
3779 switch (ins->opcode) {
3782 mask [0] = ((imask >> 0) & 3);
3783 mask [1] = ((imask >> 2) & 3);
3784 mask [2] = ((imask >> 4) & 3) + 4;
3785 mask [3] = ((imask >> 6) & 3) + 4;
3786 v1 = values [ins->sreg1];
3787 v2 = values [ins->sreg2];
3791 mask [0] = ((imask >> 0) & 1);
3792 mask [1] = ((imask >> 1) & 1) + 2;
3793 v1 = values [ins->sreg1];
3794 v2 = values [ins->sreg2];
3796 case OP_PSHUFLEW_LOW:
3798 mask [0] = ((imask >> 0) & 3);
3799 mask [1] = ((imask >> 2) & 3);
3800 mask [2] = ((imask >> 4) & 3);
3801 mask [3] = ((imask >> 6) & 3);
3806 v1 = values [ins->sreg1];
3807 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3809 case OP_PSHUFLEW_HIGH:
3815 mask [4] = 4 + ((imask >> 0) & 3);
3816 mask [5] = 4 + ((imask >> 2) & 3);
3817 mask [6] = 4 + ((imask >> 4) & 3);
3818 mask [7] = 4 + ((imask >> 6) & 3);
3819 v1 = values [ins->sreg1];
3820 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3824 mask [0] = ((imask >> 0) & 3);
3825 mask [1] = ((imask >> 2) & 3);
3826 mask [2] = ((imask >> 4) & 3);
3827 mask [3] = ((imask >> 6) & 3);
3828 v1 = values [ins->sreg1];
3829 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3832 g_assert_not_reached ();
3834 for (i = 0; i < mask_size; ++i)
3835 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3837 values [ins->dreg] =
3838 LLVMBuildShuffleVector (builder, v1, v2,
3839 LLVMConstVector (mask_values, mask_size), dname);
3843 case OP_UNPACK_LOWB:
3844 case OP_UNPACK_LOWW:
3845 case OP_UNPACK_LOWD:
3846 case OP_UNPACK_LOWQ:
3847 case OP_UNPACK_LOWPS:
3848 case OP_UNPACK_LOWPD:
3849 case OP_UNPACK_HIGHB:
3850 case OP_UNPACK_HIGHW:
3851 case OP_UNPACK_HIGHD:
3852 case OP_UNPACK_HIGHQ:
3853 case OP_UNPACK_HIGHPS:
3854 case OP_UNPACK_HIGHPD: {
3856 LLVMValueRef mask_values [16];
3857 int i, mask_size = 0;
3858 gboolean low = FALSE;
3860 switch (ins->opcode) {
3861 case OP_UNPACK_LOWB:
3865 case OP_UNPACK_LOWW:
3869 case OP_UNPACK_LOWD:
3870 case OP_UNPACK_LOWPS:
3874 case OP_UNPACK_LOWQ:
3875 case OP_UNPACK_LOWPD:
3879 case OP_UNPACK_HIGHB:
3882 case OP_UNPACK_HIGHW:
3885 case OP_UNPACK_HIGHD:
3886 case OP_UNPACK_HIGHPS:
3889 case OP_UNPACK_HIGHQ:
3890 case OP_UNPACK_HIGHPD:
3894 g_assert_not_reached ();
3898 for (i = 0; i < (mask_size / 2); ++i) {
3900 mask [(i * 2) + 1] = mask_size + i;
3903 for (i = 0; i < (mask_size / 2); ++i) {
3904 mask [(i * 2)] = (mask_size / 2) + i;
3905 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3909 for (i = 0; i < mask_size; ++i)
3910 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3912 values [ins->dreg] =
3913 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3914 LLVMConstVector (mask_values, mask_size), dname);
3919 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3920 LLVMValueRef v, val;
3922 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3923 val = LLVMConstNull (t);
3924 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3925 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3927 values [ins->dreg] = val;
3931 case OP_DUPPS_HIGH: {
3932 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3933 LLVMValueRef v1, v2, val;
3936 if (ins->opcode == OP_DUPPS_LOW) {
3937 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3938 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3940 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3941 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3943 val = LLVMConstNull (t);
3944 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3945 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3946 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3947 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3949 values [ins->dreg] = val;
3959 * EXCEPTION HANDLING
3961 case OP_IMPLICIT_EXCEPTION:
3962 /* This marks a place where an implicit exception can happen */
3963 if (bb->region != -1)
3964 LLVM_FAILURE (ctx, "implicit-exception");
3968 MonoMethodSignature *throw_sig;
3969 LLVMValueRef callee, arg;
3970 gboolean rethrow = (ins->opcode == OP_RETHROW);
3971 const char *icall_name;
3973 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3974 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3977 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3978 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3979 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3980 if (cfg->compile_aot) {
3981 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3983 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3987 * LLVM doesn't push the exception argument, so we need a different
3990 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3992 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3996 mono_memory_barrier ();
3998 ctx->lmodule->rethrow = callee;
4000 ctx->lmodule->throw = callee;
4002 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4003 emit_call (ctx, bb, &builder, callee, &arg, 1);
4006 case OP_CALL_HANDLER: {
4008 * We don't 'call' handlers, but instead simply branch to them.
4009 * The code generated by ENDFINALLY will branch back to us.
4011 LLVMBasicBlockRef noex_bb;
4013 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4015 bb_list = info->call_handler_return_bbs;
4018 * Set the indicator variable for the finally clause.
4020 lhs = info->finally_ind;
4022 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4024 /* Branch to the finally clause */
4025 LLVMBuildBr (builder, info->call_handler_target_bb);
4027 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4028 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4030 builder = ctx->builder = create_builder (ctx);
4031 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4033 bblocks [bb->block_num].end_bblock = noex_bb;
4036 case OP_START_HANDLER: {
4039 case OP_ENDFINALLY: {
4040 LLVMBasicBlockRef resume_bb;
4041 MonoBasicBlock *handler_bb;
4042 LLVMValueRef val, switch_ins, callee;
4046 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4047 g_assert (handler_bb);
4048 info = &bblocks [handler_bb->block_num];
4049 lhs = info->finally_ind;
4052 bb_list = info->call_handler_return_bbs;
4054 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4056 /* Load the finally variable */
4057 val = LLVMBuildLoad (builder, lhs, "");
4059 /* Reset the variable */
4060 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4062 /* Branch to either resume_bb, or to the bblocks in bb_list */
4063 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4065 * The other targets are added at the end to handle OP_CALL_HANDLER
4066 * opcodes processed later.
4068 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4070 builder = ctx->builder = create_builder (ctx);
4071 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4073 if (ctx->cfg->compile_aot) {
4074 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4076 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4078 LLVMBuildCall (builder, callee, NULL, 0, "");
4080 LLVMBuildUnreachable (builder);
4081 has_terminator = TRUE;
4087 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4088 LLVM_FAILURE (ctx, reason);
4093 /* Convert the value to the type required by phi nodes */
4094 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4095 if (!values [ins->dreg])
4097 values [ins->dreg] = addresses [ins->dreg];
4099 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4102 /* Add stores for volatile variables */
4103 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4104 emit_volatile_store (ctx, ins->dreg);
4107 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4108 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4110 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4111 LLVMBuildRetVoid (builder);
4113 if (bb == cfg->bb_entry)
4114 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4123 * mono_llvm_check_method_supported:
4125 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4126 * compiling a method twice.
4129 mono_llvm_check_method_supported (MonoCompile *cfg)
4131 MonoMethodHeader *header = cfg->header;
4132 MonoExceptionClause *clause;
4135 if (cfg->method->save_lmf) {
4136 cfg->exception_message = g_strdup ("lmf");
4137 cfg->disable_llvm = TRUE;
4141 for (i = 0; i < header->num_clauses; ++i) {
4142 clause = &header->clauses [i];
4144 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4146 * FIXME: Some tests still fail with nested clauses.
4148 cfg->exception_message = g_strdup ("nested clauses");
4149 cfg->disable_llvm = TRUE;
4155 if (cfg->method->dynamic) {
4156 cfg->exception_message = g_strdup ("dynamic.");
4157 cfg->disable_llvm = TRUE;
4162 * mono_llvm_emit_method:
4164 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4167 mono_llvm_emit_method (MonoCompile *cfg)
4170 MonoMethodSignature *sig;
4172 LLVMTypeRef method_type;
4173 LLVMValueRef method = NULL;
4175 LLVMValueRef *values;
4176 int i, max_block_num, bb_index;
4177 gboolean last = FALSE;
4178 GPtrArray *phi_values;
4179 LLVMCallInfo *linfo;
4181 LLVMModuleRef module;
4183 GPtrArray *bblock_list;
4184 MonoMethodHeader *header;
4185 MonoExceptionClause *clause;
4189 /* The code below might acquire the loader lock, so use it for global locking */
4190 mono_loader_lock ();
4192 /* Used to communicate with the callbacks */
4193 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4195 ctx = g_new0 (EmitContext, 1);
4197 ctx->mempool = cfg->mempool;
4200 * This maps vregs to the LLVM instruction defining them
4202 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4204 * This maps vregs for volatile variables to the LLVM instruction defining their
4207 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4208 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4209 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4210 phi_values = g_ptr_array_new ();
4212 * This signals whenever the vreg was defined by a phi node with no input vars
4213 * (i.e. all its input bblocks end with NOT_REACHABLE).
4215 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4216 /* Whenever the bblock is unreachable */
4217 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4219 bblock_list = g_ptr_array_new ();
4221 ctx->values = values;
4222 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4224 if (cfg->compile_aot) {
4225 ctx->lmodule = &aot_module;
4226 method_name = mono_aot_get_method_name (cfg);
4227 cfg->llvm_method_name = g_strdup (method_name);
4230 ctx->lmodule = &jit_module;
4231 method_name = mono_method_full_name (cfg->method, TRUE);
4234 module = ctx->module = ctx->lmodule->module;
4237 LLVM_FAILURE (ctx, "gsharedvt");
4241 static int count = 0;
4244 if (getenv ("LLVM_COUNT")) {
4245 if (count == atoi (getenv ("LLVM_COUNT"))) {
4246 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4250 if (count > atoi (getenv ("LLVM_COUNT")))
4251 LLVM_FAILURE (ctx, "");
4256 sig = mono_method_signature (cfg->method);
4259 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4261 CHECK_FAILURE (ctx);
4264 linfo->rgctx_arg = TRUE;
4265 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4266 CHECK_FAILURE (ctx);
4269 * This maps parameter indexes in the original signature to the indexes in
4270 * the LLVM signature.
4272 ctx->pindexes = sinfo.pindexes;
4274 method = LLVMAddFunction (module, method_name, method_type);
4275 ctx->lmethod = method;
4277 #ifdef LLVM_MONO_BRANCH
4278 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4280 LLVMSetLinkage (method, LLVMPrivateLinkage);
4282 LLVMAddFunctionAttr (method, LLVMUWTable);
4284 if (cfg->compile_aot) {
4285 LLVMSetLinkage (method, LLVMInternalLinkage);
4286 LLVMSetVisibility (method, LLVMHiddenVisibility);
4288 LLVMSetLinkage (method, LLVMPrivateLinkage);
4291 if (cfg->method->save_lmf)
4292 LLVM_FAILURE (ctx, "lmf");
4294 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4295 LLVM_FAILURE (ctx, "pinvoke signature");
4297 header = cfg->header;
4298 for (i = 0; i < header->num_clauses; ++i) {
4299 clause = &header->clauses [i];
4300 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4301 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4304 if (linfo->rgctx_arg) {
4305 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4307 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4308 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4309 * CC_X86_64_Mono in X86CallingConv.td.
4311 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4312 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4314 if (cfg->vret_addr) {
4315 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4316 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4319 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4320 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4323 names = g_new (char *, sig->param_count);
4324 mono_method_get_param_names (cfg->method, (const char **) names);
4326 for (i = 0; i < sig->param_count; ++i) {
4329 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4330 if (names [i] && names [i][0] != '\0')
4331 name = g_strdup_printf ("arg_%s", names [i]);
4333 name = g_strdup_printf ("arg_%d", i);
4334 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4336 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4337 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4342 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4343 max_block_num = MAX (max_block_num, bb->block_num);
4344 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4346 /* Add branches between non-consecutive bblocks */
4347 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4348 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4349 bb->next_bb != bb->last_ins->inst_false_bb) {
4351 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4352 inst->opcode = OP_BR;
4353 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4354 mono_bblock_add_inst (bb, inst);
4359 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4360 * was later optimized away, so clear these flags, and add them back for the still
4361 * present OP_LDADDR instructions.
4363 for (i = 0; i < cfg->next_vreg; ++i) {
4366 ins = get_vreg_to_inst (cfg, i);
4367 if (ins && ins != cfg->rgctx_var)
4368 ins->flags &= ~MONO_INST_INDIRECT;
4372 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4374 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4376 LLVMBuilderRef builder;
4378 char dname_buf[128];
4380 builder = create_builder (ctx);
4382 for (ins = bb->code; ins; ins = ins->next) {
4383 switch (ins->opcode) {
4388 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4390 CHECK_FAILURE (ctx);
4392 if (ins->opcode == OP_VPHI) {
4393 /* Treat valuetype PHI nodes as operating on the address itself */
4394 g_assert (ins->klass);
4395 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4399 * Have to precreate these, as they can be referenced by
4400 * earlier instructions.
4402 sprintf (dname_buf, "t%d", ins->dreg);
4404 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4406 if (ins->opcode == OP_VPHI)
4407 ctx->addresses [ins->dreg] = values [ins->dreg];
4409 g_ptr_array_add (phi_values, values [ins->dreg]);
4412 * Set the expected type of the incoming arguments since these have
4413 * to have the same type.
4415 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4416 int sreg1 = ins->inst_phi_args [i + 1];
4419 ctx->vreg_types [sreg1] = phi_type;
4424 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4433 * Create an ordering for bblocks, use the depth first order first, then
4434 * put the exception handling bblocks last.
4436 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4437 bb = cfg->bblocks [bb_index];
4438 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4439 g_ptr_array_add (bblock_list, bb);
4440 bblocks [bb->block_num].added = TRUE;
4444 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4445 if (!bblocks [bb->block_num].added)
4446 g_ptr_array_add (bblock_list, bb);
4450 * Second pass: generate code.
4452 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4453 bb = g_ptr_array_index (bblock_list, bb_index);
4455 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4458 process_bb (ctx, bb);
4459 CHECK_FAILURE (ctx);
4462 /* Add incoming phi values */
4463 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4464 GSList *l, *ins_list;
4466 ins_list = bblocks [bb->block_num].phi_nodes;
4468 for (l = ins_list; l; l = l->next) {
4469 PhiNode *node = l->data;
4470 MonoInst *phi = node->phi;
4471 int sreg1 = node->sreg;
4472 LLVMBasicBlockRef in_bb;
4477 in_bb = get_end_bb (ctx, node->in_bb);
4479 if (ctx->unreachable [node->in_bb->block_num])
4482 if (!values [sreg1])
4483 /* Can happen with values in EH clauses */
4484 LLVM_FAILURE (ctx, "incoming phi sreg1");
4486 if (phi->opcode == OP_VPHI) {
4487 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4488 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4490 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4491 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4496 /* Create the SWITCH statements for ENDFINALLY instructions */
4497 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4498 BBInfo *info = &bblocks [bb->block_num];
4500 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4501 LLVMValueRef switch_ins = l->data;
4502 GSList *bb_list = info->call_handler_return_bbs;
4504 for (i = 0; i < g_slist_length (bb_list); ++i)
4505 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4509 if (cfg->verbose_level > 1)
4510 mono_llvm_dump_value (method);
4512 mark_as_used (module, method);
4514 if (cfg->compile_aot) {
4515 LLVMValueRef md_args [16];
4516 LLVMValueRef md_node;
4519 method_index = mono_aot_get_method_index (cfg->orig_method);
4520 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4521 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4522 md_node = LLVMMDNode (md_args, 2);
4523 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4524 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4527 if (cfg->compile_aot) {
4528 /* Don't generate native code, keep the LLVM IR */
4529 if (cfg->compile_aot && cfg->verbose_level)
4530 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4532 //LLVMVerifyFunction(method, 0);
4534 mono_llvm_optimize_method (method);
4536 if (cfg->verbose_level > 1)
4537 mono_llvm_dump_value (method);
4539 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4541 /* Set by emit_cb */
4542 g_assert (cfg->code_len);
4544 /* FIXME: Free the LLVM IL for the function */
4552 /* Need to add unused phi nodes as they can be referenced by other values */
4553 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4554 LLVMBuilderRef builder;
4556 builder = create_builder (ctx);
4557 LLVMPositionBuilderAtEnd (builder, phi_bb);
4559 for (i = 0; i < phi_values->len; ++i) {
4560 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4561 if (LLVMGetInstructionParent (v) == NULL)
4562 LLVMInsertIntoBuilder (builder, v);
4565 LLVMDeleteFunction (method);
4570 g_free (ctx->addresses);
4571 g_free (ctx->vreg_types);
4572 g_free (ctx->vreg_cli_types);
4573 g_free (ctx->pindexes);
4574 g_free (ctx->is_dead);
4575 g_free (ctx->unreachable);
4576 g_ptr_array_free (phi_values, TRUE);
4577 g_free (ctx->bblocks);
4578 g_hash_table_destroy (ctx->region_to_handler);
4579 g_free (method_name);
4580 g_ptr_array_free (bblock_list, TRUE);
4582 for (l = ctx->builders; l; l = l->next) {
4583 LLVMBuilderRef builder = l->data;
4584 LLVMDisposeBuilder (builder);
4589 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4591 mono_loader_unlock ();
4595 * mono_llvm_emit_call:
4597 * Same as mono_arch_emit_call () for LLVM.
4600 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4603 MonoMethodSignature *sig;
4604 int i, n, stack_size;
4609 sig = call->signature;
4610 n = sig->param_count + sig->hasthis;
4612 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4614 if (cfg->disable_llvm)
4617 if (sig->call_convention == MONO_CALL_VARARG) {
4618 cfg->exception_message = g_strdup ("varargs");
4619 cfg->disable_llvm = TRUE;
4622 for (i = 0; i < n; ++i) {
4625 ainfo = call->cinfo->args + i;
4627 in = call->args [i];
4629 /* Simply remember the arguments */
4630 switch (ainfo->storage) {
4632 case LLVMArgInFPReg: {
4633 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4635 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4636 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4637 ins->dreg = mono_alloc_freg (cfg);
4639 MONO_INST_NEW (cfg, ins, OP_MOVE);
4640 ins->dreg = mono_alloc_ireg (cfg);
4642 ins->sreg1 = in->dreg;
4645 case LLVMArgVtypeByVal:
4646 case LLVMArgVtypeInReg:
4647 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4648 ins->dreg = mono_alloc_ireg (cfg);
4649 ins->sreg1 = in->dreg;
4650 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4653 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4654 cfg->exception_message = g_strdup ("ainfo->storage");
4655 cfg->disable_llvm = TRUE;
4659 if (!cfg->disable_llvm) {
4660 MONO_ADD_INS (cfg->cbb, ins);
4661 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4666 static unsigned char*
4667 alloc_cb (LLVMValueRef function, int size)
4671 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4675 return mono_domain_code_reserve (cfg->domain, size);
4677 return mono_domain_code_reserve (mono_domain_get (), size);
4682 emitted_cb (LLVMValueRef function, void *start, void *end)
4686 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4688 cfg->code_len = (guint8*)end - (guint8*)start;
4692 exception_cb (void *data)
4695 MonoJitExceptionInfo *ei;
4696 guint32 ei_len, i, j, nested_len, nindex;
4697 gpointer *type_info;
4698 int this_reg, this_offset;
4700 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4704 * data points to a DWARF FDE structure, convert it to our unwind format and
4706 * An alternative would be to save it directly, and modify our unwinder to work
4709 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);
4711 /* Count nested clauses */
4713 for (i = 0; i < ei_len; ++i) {
4714 for (j = 0; j < ei_len; ++j) {
4715 gint32 cindex1 = *(gint32*)type_info [i];
4716 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4717 gint32 cindex2 = *(gint32*)type_info [j];
4718 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4720 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4726 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4727 cfg->llvm_ex_info_len = ei_len + nested_len;
4728 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4729 /* Fill the rest of the information from the type info */
4730 for (i = 0; i < ei_len; ++i) {
4731 gint32 clause_index = *(gint32*)type_info [i];
4732 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4734 cfg->llvm_ex_info [i].flags = clause->flags;
4735 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4739 * For nested clauses, the LLVM produced exception info associates the try interval with
4740 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4742 /* FIXME: These should be order with the normal clauses */
4744 for (i = 0; i < ei_len; ++i) {
4745 for (j = 0; j < ei_len; ++j) {
4746 gint32 cindex1 = *(gint32*)type_info [i];
4747 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4748 gint32 cindex2 = *(gint32*)type_info [j];
4749 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4751 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4753 * The try interval comes from the nested clause, everything else from the
4756 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4757 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4758 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4763 g_assert (nindex == ei_len + nested_len);
4764 cfg->llvm_this_reg = this_reg;
4765 cfg->llvm_this_offset = this_offset;
4767 /* type_info [i] is cfg mempool allocated, no need to free it */
4774 dlsym_cb (const char *name, void **symbol)
4780 if (!strcmp (name, "__bzero")) {
4781 *symbol = (void*)bzero;
4783 current = mono_dl_open (NULL, 0, NULL);
4786 err = mono_dl_symbol (current, name, symbol);
4788 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4789 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4795 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4797 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4801 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4803 LLVMTypeRef param_types [4];
4805 param_types [0] = param_type1;
4806 param_types [1] = param_type2;
4808 AddFunc (module, name, ret_type, param_types, 2);
4812 add_intrinsics (LLVMModuleRef module)
4814 /* Emit declarations of instrinsics */
4816 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4817 * type doesn't seem to do any locking.
4820 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4822 memset_param_count = 5;
4823 memset_func_name = "llvm.memset.p0i8.i32";
4825 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4829 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4831 memcpy_param_count = 5;
4832 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4834 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4838 LLVMTypeRef params [] = { LLVMDoubleType () };
4840 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4841 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4842 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4844 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4845 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4849 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4850 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4852 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4853 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4854 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4855 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4856 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4857 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4861 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4862 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4864 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4865 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4866 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4867 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4868 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4869 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4873 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4874 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4875 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4877 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4879 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4884 LLVMTypeRef arg_types [2];
4885 LLVMTypeRef ret_type;
4887 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4888 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4889 ret_type = LLVMInt32Type ();
4891 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4893 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4896 /* SSE intrinsics */
4898 LLVMTypeRef ret_type, arg_types [16];
4901 ret_type = type_to_simd_type (MONO_TYPE_I4);
4902 arg_types [0] = ret_type;
4903 arg_types [1] = ret_type;
4904 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4905 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4907 ret_type = type_to_simd_type (MONO_TYPE_I2);
4908 arg_types [0] = ret_type;
4909 arg_types [1] = ret_type;
4910 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4911 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4912 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4913 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4914 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4915 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4916 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4917 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4918 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4919 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4921 ret_type = type_to_simd_type (MONO_TYPE_I1);
4922 arg_types [0] = ret_type;
4923 arg_types [1] = ret_type;
4924 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4925 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4926 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4927 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4928 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4930 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4932 ret_type = type_to_simd_type (MONO_TYPE_R8);
4933 arg_types [0] = ret_type;
4934 arg_types [1] = ret_type;
4935 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4936 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4937 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4938 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4939 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4941 ret_type = type_to_simd_type (MONO_TYPE_R4);
4942 arg_types [0] = ret_type;
4943 arg_types [1] = ret_type;
4944 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4945 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4946 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4947 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4948 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4951 ret_type = type_to_simd_type (MONO_TYPE_I1);
4952 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4953 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4954 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4955 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4956 ret_type = type_to_simd_type (MONO_TYPE_I2);
4957 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4958 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4959 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4960 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4963 ret_type = type_to_simd_type (MONO_TYPE_R8);
4964 arg_types [0] = ret_type;
4965 arg_types [1] = ret_type;
4966 arg_types [2] = LLVMInt8Type ();
4967 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4968 ret_type = type_to_simd_type (MONO_TYPE_R4);
4969 arg_types [0] = ret_type;
4970 arg_types [1] = ret_type;
4971 arg_types [2] = LLVMInt8Type ();
4972 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4974 /* Conversion ops */
4975 ret_type = type_to_simd_type (MONO_TYPE_R8);
4976 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4977 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4978 ret_type = type_to_simd_type (MONO_TYPE_R4);
4979 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4980 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4981 ret_type = type_to_simd_type (MONO_TYPE_I4);
4982 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4983 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4984 ret_type = type_to_simd_type (MONO_TYPE_I4);
4985 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4986 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4987 ret_type = type_to_simd_type (MONO_TYPE_R4);
4988 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4989 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4990 ret_type = type_to_simd_type (MONO_TYPE_R8);
4991 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4992 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4994 ret_type = type_to_simd_type (MONO_TYPE_I4);
4995 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4996 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4997 ret_type = type_to_simd_type (MONO_TYPE_I4);
4998 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4999 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5002 ret_type = type_to_simd_type (MONO_TYPE_R8);
5003 arg_types [0] = ret_type;
5004 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5005 ret_type = type_to_simd_type (MONO_TYPE_R4);
5006 arg_types [0] = ret_type;
5007 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5008 ret_type = type_to_simd_type (MONO_TYPE_R4);
5009 arg_types [0] = ret_type;
5010 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5011 ret_type = type_to_simd_type (MONO_TYPE_R4);
5012 arg_types [0] = ret_type;
5013 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5016 ret_type = type_to_simd_type (MONO_TYPE_I2);
5017 arg_types [0] = ret_type;
5018 arg_types [1] = LLVMInt32Type ();
5019 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5020 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5021 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5022 ret_type = type_to_simd_type (MONO_TYPE_I4);
5023 arg_types [0] = ret_type;
5024 arg_types [1] = LLVMInt32Type ();
5025 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5026 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5027 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5028 ret_type = type_to_simd_type (MONO_TYPE_I8);
5029 arg_types [0] = ret_type;
5030 arg_types [1] = LLVMInt32Type ();
5031 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5032 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5035 ret_type = LLVMInt32Type ();
5036 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5037 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5040 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5042 /* Load/Store intrinsics */
5044 LLVMTypeRef arg_types [5];
5048 for (i = 1; i <= 8; i *= 2) {
5049 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5050 arg_types [1] = LLVMInt32Type ();
5051 arg_types [2] = LLVMInt1Type ();
5052 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5053 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5055 arg_types [0] = LLVMIntType (i * 8);
5056 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5057 arg_types [2] = LLVMInt32Type ();
5058 arg_types [3] = LLVMInt1Type ();
5059 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5060 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5066 mono_llvm_init (void)
5068 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5072 init_jit_module (void)
5074 MonoJitICallInfo *info;
5076 if (jit_module_inited)
5079 mono_loader_lock ();
5081 if (jit_module_inited) {
5082 mono_loader_unlock ();
5086 jit_module.module = LLVMModuleCreateWithName ("mono");
5088 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5090 add_intrinsics (jit_module.module);
5092 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5094 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5096 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5098 jit_module_inited = TRUE;
5100 mono_loader_unlock ();
5104 mono_llvm_cleanup (void)
5107 mono_llvm_dispose_ee (ee);
5109 if (jit_module.llvm_types)
5110 g_hash_table_destroy (jit_module.llvm_types);
5112 if (aot_module.module)
5113 LLVMDisposeModule (aot_module.module);
5115 LLVMContextDispose (LLVMGetGlobalContext ());
5119 mono_llvm_create_aot_module (const char *got_symbol)
5121 /* Delete previous module */
5122 if (aot_module.plt_entries)
5123 g_hash_table_destroy (aot_module.plt_entries);
5124 if (aot_module.module)
5125 LLVMDisposeModule (aot_module.module);
5127 memset (&aot_module, 0, sizeof (aot_module));
5129 aot_module.module = LLVMModuleCreateWithName ("aot");
5130 aot_module.got_symbol = got_symbol;
5132 add_intrinsics (aot_module.module);
5136 * We couldn't compute the type of the LLVM global representing the got because
5137 * its size is only known after all the methods have been emitted. So create
5138 * a dummy variable, and replace all uses it with the real got variable when
5139 * its size is known in mono_llvm_emit_aot_module ().
5142 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5144 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5145 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5148 /* Add a dummy personality function */
5150 LLVMBasicBlockRef lbb;
5151 LLVMBuilderRef lbuilder;
5152 LLVMValueRef personality;
5154 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5155 LLVMSetLinkage (personality, LLVMInternalLinkage);
5156 lbb = LLVMAppendBasicBlock (personality, "BB0");
5157 lbuilder = LLVMCreateBuilder ();
5158 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5159 LLVMBuildRetVoid (lbuilder);
5162 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5163 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5167 * Emit the aot module into the LLVM bitcode file FILENAME.
5170 mono_llvm_emit_aot_module (const char *filename, int got_size)
5172 LLVMTypeRef got_type;
5173 LLVMValueRef real_got;
5176 * Create the real got variable and replace all uses of the dummy variable with
5179 got_type = LLVMArrayType (IntPtrType (), got_size);
5180 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5181 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5182 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5184 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5186 mark_as_used (aot_module.module, real_got);
5188 /* Delete the dummy got so it doesn't become a global */
5189 LLVMDeleteGlobal (aot_module.got_var);
5195 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5196 g_assert_not_reached ();
5201 LLVMWriteBitcodeToFile (aot_module.module, filename);
5206 - Emit LLVM IR from the mono IR using the LLVM C API.
5207 - The original arch specific code remains, so we can fall back to it if we run
5208 into something we can't handle.
5212 A partial list of issues:
5213 - Handling of opcodes which can throw exceptions.
5215 In the mono JIT, these are implemented using code like this:
5222 push throw_pos - method
5223 call <exception trampoline>
5225 The problematic part is push throw_pos - method, which cannot be represented
5226 in the LLVM IR, since it does not support label values.
5227 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5228 be implemented in JIT mode ?
5229 -> a possible but slower implementation would use the normal exception
5230 throwing code but it would need to control the placement of the throw code
5231 (it needs to be exactly after the compare+branch).
5232 -> perhaps add a PC offset intrinsics ?
5234 - efficient implementation of .ovf opcodes.
5236 These are currently implemented as:
5237 <ins which sets the condition codes>
5240 Some overflow opcodes are now supported by LLVM SVN.
5242 - exception handling, unwinding.
5243 - SSA is disabled for methods with exception handlers
5244 - How to obtain unwind info for LLVM compiled methods ?
5245 -> this is now solved by converting the unwind info generated by LLVM
5247 - LLVM uses the c++ exception handling framework, while we use our home grown
5248 code, and couldn't use the c++ one:
5249 - its not supported under VC++, other exotic platforms.
5250 - it might be impossible to support filter clauses with it.
5254 The trampolines need a predictable call sequence, since they need to disasm
5255 the calling code to obtain register numbers / offsets.
5257 LLVM currently generates this code in non-JIT mode:
5258 mov -0x98(%rax),%eax
5260 Here, the vtable pointer is lost.
5261 -> solution: use one vtable trampoline per class.
5263 - passing/receiving the IMT pointer/RGCTX.
5264 -> solution: pass them as normal arguments ?
5268 LLVM does not allow the specification of argument registers etc. This means
5269 that all calls are made according to the platform ABI.
5271 - passing/receiving vtypes.
5273 Vtypes passed/received in registers are handled by the front end by using
5274 a signature with scalar arguments, and loading the parts of the vtype into those
5277 Vtypes passed on the stack are handled using the 'byval' attribute.
5281 Supported though alloca, we need to emit the load/store code.
5285 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5286 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5287 This is made easier because the IR is already in SSA form.
5288 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5289 types are frequently used incorrectly.
5294 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5295 append the AOT data structures to that file. For methods which cannot be
5296 handled by LLVM, the normal JIT compiled versions are used.
5299 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5300 * - each bblock should end with a branch
5301 * - setting the return value, making cfg->ret non-volatile
5302 * - avoid some transformations in the JIT which make it harder for us to generate
5304 * - use pointer types to help optimizations.