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 #ifdef MONO_ARCH_SIMD_INTRINSICS
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 #ifdef MONO_ARCH_SIMD_INTRINSICS
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 #ifdef MONO_ARCH_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 && MONO_TYPE_ISSTRUCT (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) || MONO_TYPE_ISSTRUCT (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 (!MONO_TYPE_ISSTRUCT (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);
1870 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1876 memset (&ji, 0, sizeof (ji));
1877 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1878 ji.data.target = info->name;
1880 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1882 if (cfg->compile_aot) {
1883 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1885 LLVM_FAILURE (ctx, "can't encode patch");
1887 callee = LLVMAddFunction (module, "", llvm_sig);
1888 target = (gpointer)mono_icall_get_wrapper (info);
1889 LLVMAddGlobalMapping (ee, callee, target);
1892 if (cfg->compile_aot) {
1894 if (cfg->abs_patches) {
1895 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1897 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1899 LLVM_FAILURE (ctx, "can't encode patch");
1903 LLVM_FAILURE (ctx, "aot");
1905 callee = LLVMAddFunction (module, "", llvm_sig);
1907 if (cfg->abs_patches) {
1908 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1911 * FIXME: Some trampolines might have
1912 * their own calling convention on some platforms.
1914 #ifndef TARGET_AMD64
1915 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)
1916 LLVM_FAILURE (ctx, "trampoline with own cconv");
1918 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1919 LLVMAddGlobalMapping (ee, callee, target);
1923 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1929 int size = sizeof (gpointer);
1932 g_assert (ins->inst_offset % size == 0);
1933 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1935 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1937 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1939 if (ins->flags & MONO_INST_HAS_METHOD) {
1944 * Collect and convert arguments
1946 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
1947 args = alloca (len);
1948 memset (args, 0, len);
1949 l = call->out_ireg_args;
1951 if (call->rgctx_arg_reg) {
1952 g_assert (values [call->rgctx_arg_reg]);
1953 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1955 if (call->imt_arg_reg) {
1956 g_assert (values [call->imt_arg_reg]);
1957 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1961 if (!addresses [call->inst.dreg])
1962 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1963 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1966 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1969 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1973 pindex = sinfo.this_arg_pindex;
1975 pindex = sinfo.pindexes [i - 1];
1977 pindex = sinfo.pindexes [i];
1980 regpair = (guint32)(gssize)(l->data);
1981 reg = regpair & 0xffffff;
1982 args [pindex] = values [reg];
1983 if (ainfo->storage == LLVMArgVtypeInReg) {
1985 LLVMValueRef regs [2];
1990 g_assert (addresses [reg]);
1992 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
1993 for (j = 0; j < nregs; ++j)
1994 args [pindex ++] = regs [j];
1997 // FIXME: Get rid of the VMOVE
1998 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1999 g_assert (addresses [reg]);
2000 args [pindex] = addresses [reg];
2002 g_assert (args [pindex]);
2003 if (i == 0 && sig->hasthis)
2004 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2006 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2012 // FIXME: Align call sites
2018 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2020 #ifdef LLVM_MONO_BRANCH
2022 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2024 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2025 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2027 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2028 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2030 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2032 if (call->rgctx_arg_reg)
2033 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2034 if (call->imt_arg_reg)
2035 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2038 /* Add byval attributes if needed */
2039 for (i = 0; i < sig->param_count; ++i) {
2040 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2042 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2043 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2048 * Convert the result
2050 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2051 LLVMValueRef regs [2];
2053 if (!addresses [ins->dreg])
2054 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2056 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2057 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2058 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2060 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2061 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2062 /* If the method returns an unsigned value, need to zext it */
2064 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));
2067 *builder_ref = ctx->builder;
2069 g_free (sinfo.pindexes);
2077 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2079 MonoCompile *cfg = ctx->cfg;
2080 MonoMethodSignature *sig = ctx->sig;
2081 LLVMValueRef method = ctx->lmethod;
2082 LLVMValueRef *values = ctx->values;
2083 LLVMValueRef *addresses = ctx->addresses;
2085 LLVMCallInfo *linfo = ctx->linfo;
2086 LLVMModuleRef module = ctx->module;
2087 BBInfo *bblocks = ctx->bblocks;
2089 LLVMBasicBlockRef cbb;
2090 LLVMBuilderRef builder, starting_builder;
2091 gboolean has_terminator;
2093 LLVMValueRef lhs, rhs;
2096 cbb = get_bb (ctx, bb);
2097 builder = create_builder (ctx);
2098 ctx->builder = builder;
2099 LLVMPositionBuilderAtEnd (builder, cbb);
2101 if (bb == cfg->bb_entry)
2102 emit_entry_bb (ctx, builder);
2103 CHECK_FAILURE (ctx);
2105 if (bb->flags & BB_EXCEPTION_HANDLER) {
2107 LLVMValueRef personality;
2108 LLVMBasicBlockRef target_bb;
2110 static gint32 mapping_inited;
2111 static int ti_generator;
2114 LLVMValueRef type_info;
2117 if (!bblocks [bb->block_num].invoke_target) {
2119 * LLVM asserts if llvm.eh.selector is called from a bblock which
2120 * doesn't have an invoke pointing at it.
2121 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2123 LLVM_FAILURE (ctx, "handler without invokes");
2126 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2128 if (cfg->compile_aot) {
2129 /* Use a dummy personality function */
2130 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2131 g_assert (personality);
2133 personality = LLVMGetNamedFunction (module, "mono_personality");
2134 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2135 LLVMAddGlobalMapping (ee, personality, mono_personality);
2138 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2140 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2143 * Create the type info
2145 sprintf (ti_name, "type_info_%d", ti_generator);
2148 if (cfg->compile_aot) {
2149 /* decode_eh_frame () in aot-runtime.c will decode this */
2150 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2151 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2153 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2154 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2157 * Enabling this causes llc to crash:
2158 * http://llvm.org/bugs/show_bug.cgi?id=6102
2160 //LLVM_FAILURE (ctx, "aot+clauses");
2162 // test_0_invalid_unbox_arrays () fails
2163 LLVM_FAILURE (ctx, "aot+clauses");
2167 * After the cfg mempool is freed, the type info will point to stale memory,
2168 * but this is not a problem, since we decode it once in exception_cb during
2171 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2172 *(gint32*)ti = clause_index;
2174 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2176 LLVMAddGlobalMapping (ee, type_info, ti);
2180 LLVMTypeRef members [2], ret_type;
2181 LLVMValueRef landing_pad;
2183 members [0] = i8ptr;
2184 members [1] = LLVMInt32Type ();
2185 ret_type = LLVMStructType (members, 2, FALSE);
2187 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2188 LLVMAddClause (landing_pad, type_info);
2190 /* Store the exception into the exvar */
2191 if (bb->in_scount == 1) {
2192 g_assert (bb->in_scount == 1);
2193 exvar = bb->in_stack [0];
2195 // FIXME: This is shared with filter clauses ?
2196 g_assert (!values [exvar->dreg]);
2198 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2199 emit_volatile_store (ctx, exvar->dreg);
2203 /* Start a new bblock which CALL_HANDLER can branch to */
2204 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2206 LLVMBuildBr (builder, target_bb);
2208 ctx->builder = builder = create_builder (ctx);
2209 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2211 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2215 has_terminator = FALSE;
2216 starting_builder = builder;
2217 for (ins = bb->code; ins; ins = ins->next) {
2218 const char *spec = LLVM_INS_INFO (ins->opcode);
2220 char dname_buf [128];
2223 if (nins > 5000 && builder == starting_builder) {
2224 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2225 LLVM_FAILURE (ctx, "basic block too long");
2229 /* There could be instructions after a terminator, skip them */
2232 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2233 sprintf (dname_buf, "t%d", ins->dreg);
2237 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2238 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2240 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2241 lhs = emit_volatile_load (ctx, ins->sreg1);
2243 /* It is ok for SETRET to have an uninitialized argument */
2244 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2245 LLVM_FAILURE (ctx, "sreg1");
2246 lhs = values [ins->sreg1];
2252 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2253 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2254 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2255 rhs = emit_volatile_load (ctx, ins->sreg2);
2257 if (!values [ins->sreg2])
2258 LLVM_FAILURE (ctx, "sreg2");
2259 rhs = values [ins->sreg2];
2265 //mono_print_ins (ins);
2266 switch (ins->opcode) {
2269 case OP_LIVERANGE_START:
2270 case OP_LIVERANGE_END:
2273 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2276 #if SIZEOF_VOID_P == 4
2277 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2279 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2283 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2286 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2289 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2290 has_terminator = TRUE;
2296 LLVMBasicBlockRef new_bb;
2297 LLVMBuilderRef new_builder;
2299 // The default branch is already handled
2300 // FIXME: Handle it here
2302 /* Start new bblock */
2303 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2304 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2306 lhs = convert (ctx, lhs, LLVMInt32Type ());
2307 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2308 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2309 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2311 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2314 new_builder = create_builder (ctx);
2315 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2316 LLVMBuildUnreachable (new_builder);
2318 has_terminator = TRUE;
2319 g_assert (!ins->next);
2325 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2326 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2327 LLVMValueRef part1, retval;
2330 size = get_vtype_size (sig->ret);
2332 g_assert (addresses [ins->sreg1]);
2334 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2335 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2337 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2339 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2341 LLVMBuildRet (builder, retval);
2345 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2346 LLVMBuildRetVoid (builder);
2350 if (!lhs || ctx->is_dead [ins->sreg1]) {
2352 * The method did not set its return value, probably because it
2353 * ends with a throw.
2356 LLVMBuildRetVoid (builder);
2358 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2360 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2362 has_terminator = TRUE;
2368 case OP_ICOMPARE_IMM:
2369 case OP_LCOMPARE_IMM:
2370 case OP_COMPARE_IMM: {
2374 if (ins->next->opcode == OP_NOP)
2377 if (ins->next->opcode == OP_BR)
2378 /* The comparison result is not needed */
2381 rel = mono_opcode_to_cond (ins->next->opcode);
2383 if (ins->opcode == OP_ICOMPARE_IMM) {
2384 lhs = convert (ctx, lhs, LLVMInt32Type ());
2385 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2387 if (ins->opcode == OP_LCOMPARE_IMM) {
2388 lhs = convert (ctx, lhs, LLVMInt64Type ());
2389 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2391 if (ins->opcode == OP_LCOMPARE) {
2392 lhs = convert (ctx, lhs, LLVMInt64Type ());
2393 rhs = convert (ctx, rhs, LLVMInt64Type ());
2395 if (ins->opcode == OP_ICOMPARE) {
2396 lhs = convert (ctx, lhs, LLVMInt32Type ());
2397 rhs = convert (ctx, rhs, LLVMInt32Type ());
2401 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2402 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2403 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2404 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2407 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2408 if (ins->opcode == OP_FCOMPARE)
2409 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2410 else if (ins->opcode == OP_COMPARE_IMM)
2411 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2412 else if (ins->opcode == OP_LCOMPARE_IMM) {
2413 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2414 /* The immediate is encoded in two fields */
2415 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2416 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2418 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2421 else if (ins->opcode == OP_COMPARE)
2422 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2424 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2426 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2427 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2429 * If the target bb contains PHI instructions, LLVM requires
2430 * two PHI entries for this bblock, while we only generate one.
2431 * So convert this to an unconditional bblock. (bxc #171).
2433 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2435 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2437 has_terminator = TRUE;
2438 } else if (MONO_IS_SETCC (ins->next)) {
2439 sprintf (dname_buf, "t%d", ins->next->dreg);
2441 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2443 /* Add stores for volatile variables */
2444 emit_volatile_store (ctx, ins->next->dreg);
2445 } else if (MONO_IS_COND_EXC (ins->next)) {
2446 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2447 CHECK_FAILURE (ctx);
2448 builder = ctx->builder;
2450 LLVM_FAILURE (ctx, "next");
2464 rel = mono_opcode_to_cond (ins->opcode);
2466 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2467 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2475 gboolean empty = TRUE;
2477 /* Check that all input bblocks really branch to us */
2478 for (i = 0; i < bb->in_count; ++i) {
2479 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2480 ins->inst_phi_args [i + 1] = -1;
2486 /* LLVM doesn't like phi instructions with zero operands */
2487 ctx->is_dead [ins->dreg] = TRUE;
2491 /* Created earlier, insert it now */
2492 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2494 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2495 int sreg1 = ins->inst_phi_args [i + 1];
2499 * Count the number of times the incoming bblock branches to us,
2500 * since llvm requires a separate entry for each.
2502 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2503 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2506 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2507 if (switch_ins->inst_many_bb [j] == bb)
2514 /* Remember for later */
2515 for (j = 0; j < count; ++j) {
2516 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2519 node->in_bb = bb->in_bb [i];
2521 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);
2531 values [ins->dreg] = lhs;
2534 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2537 values [ins->dreg] = lhs;
2539 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2541 * This is added by the spilling pass in case of the JIT,
2542 * but we have to do it ourselves.
2544 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2578 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2579 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2581 switch (ins->opcode) {
2584 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2588 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2592 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2596 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2600 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2604 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2608 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2611 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2615 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2619 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2623 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2627 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2631 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2635 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2639 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2642 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2645 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2649 g_assert_not_reached ();
2656 case OP_IREM_UN_IMM:
2658 case OP_IDIV_UN_IMM:
2664 case OP_ISHR_UN_IMM:
2673 case OP_LSHR_UN_IMM:
2681 if (spec [MONO_INST_SRC1] == 'l') {
2682 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2684 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2687 #if SIZEOF_VOID_P == 4
2688 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2689 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2692 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2693 lhs = convert (ctx, lhs, IntPtrType ());
2694 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2695 switch (ins->opcode) {
2699 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2703 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2707 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2711 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2713 case OP_IDIV_UN_IMM:
2714 case OP_LDIV_UN_IMM:
2715 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2719 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2721 case OP_IREM_UN_IMM:
2722 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2727 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2731 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2735 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2740 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2745 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2747 case OP_ISHR_UN_IMM:
2748 /* This is used to implement conv.u4, so the lhs could be an i8 */
2749 lhs = convert (ctx, lhs, LLVMInt32Type ());
2750 imm = convert (ctx, imm, LLVMInt32Type ());
2751 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2753 case OP_LSHR_UN_IMM:
2754 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2757 g_assert_not_reached ();
2762 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2765 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2768 lhs = convert (ctx, lhs, LLVMDoubleType ());
2769 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2772 guint32 v = 0xffffffff;
2773 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2777 guint64 v = 0xffffffffffffffffLL;
2778 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2781 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2783 LLVMValueRef v1, v2;
2785 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2786 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2787 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2792 case OP_ICONV_TO_I1:
2793 case OP_ICONV_TO_I2:
2794 case OP_ICONV_TO_I4:
2795 case OP_ICONV_TO_U1:
2796 case OP_ICONV_TO_U2:
2797 case OP_ICONV_TO_U4:
2798 case OP_LCONV_TO_I1:
2799 case OP_LCONV_TO_I2:
2800 case OP_LCONV_TO_U1:
2801 case OP_LCONV_TO_U2:
2802 case OP_LCONV_TO_U4: {
2805 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);
2807 /* Have to do two casts since our vregs have type int */
2808 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2810 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2812 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2815 case OP_ICONV_TO_I8:
2816 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2818 case OP_ICONV_TO_U8:
2819 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2821 case OP_FCONV_TO_I4:
2822 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2824 case OP_FCONV_TO_I1:
2825 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2827 case OP_FCONV_TO_U1:
2828 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2830 case OP_FCONV_TO_I2:
2831 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2833 case OP_FCONV_TO_U2:
2834 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2836 case OP_FCONV_TO_I8:
2837 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2840 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2842 case OP_ICONV_TO_R8:
2843 case OP_LCONV_TO_R8:
2844 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2846 case OP_LCONV_TO_R_UN:
2847 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2849 #if SIZEOF_VOID_P == 4
2852 case OP_LCONV_TO_I4:
2853 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2855 case OP_ICONV_TO_R4:
2856 case OP_LCONV_TO_R4:
2857 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2858 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2860 case OP_FCONV_TO_R4:
2861 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2862 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2865 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2868 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2871 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2873 case OP_LOCALLOC_IMM: {
2876 guint32 size = ins->inst_imm;
2877 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2879 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2881 if (ins->flags & MONO_INST_INIT) {
2882 LLVMValueRef args [5];
2885 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2886 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2887 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2888 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2889 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2892 values [ins->dreg] = v;
2896 LLVMValueRef v, size;
2898 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), "");
2900 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2902 if (ins->flags & MONO_INST_INIT) {
2903 LLVMValueRef args [5];
2906 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2908 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2909 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2910 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2912 values [ins->dreg] = v;
2916 case OP_LOADI1_MEMBASE:
2917 case OP_LOADU1_MEMBASE:
2918 case OP_LOADI2_MEMBASE:
2919 case OP_LOADU2_MEMBASE:
2920 case OP_LOADI4_MEMBASE:
2921 case OP_LOADU4_MEMBASE:
2922 case OP_LOADI8_MEMBASE:
2923 case OP_LOADR4_MEMBASE:
2924 case OP_LOADR8_MEMBASE:
2925 case OP_LOAD_MEMBASE:
2933 LLVMValueRef base, index, addr;
2935 gboolean sext = FALSE, zext = FALSE;
2936 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2938 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2943 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)) {
2944 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2949 if (ins->inst_offset == 0) {
2951 } else if (ins->inst_offset % size != 0) {
2952 /* Unaligned load */
2953 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2954 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2956 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2957 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2961 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2963 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2965 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2967 * These will signal LLVM that these loads do not alias any stores, and
2968 * they can't fail, allowing them to be hoisted out of loops.
2970 set_metadata_flag (values [ins->dreg], "mono.noalias");
2971 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2975 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2977 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2978 else if (ins->opcode == OP_LOADR4_MEMBASE)
2979 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2983 case OP_STOREI1_MEMBASE_REG:
2984 case OP_STOREI2_MEMBASE_REG:
2985 case OP_STOREI4_MEMBASE_REG:
2986 case OP_STOREI8_MEMBASE_REG:
2987 case OP_STORER4_MEMBASE_REG:
2988 case OP_STORER8_MEMBASE_REG:
2989 case OP_STORE_MEMBASE_REG: {
2991 LLVMValueRef index, addr;
2993 gboolean sext = FALSE, zext = FALSE;
2994 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2996 if (!values [ins->inst_destbasereg])
2997 LLVM_FAILURE (ctx, "inst_destbasereg");
2999 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3001 if (ins->inst_offset % size != 0) {
3002 /* Unaligned store */
3003 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3004 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3006 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3007 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3009 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3013 case OP_STOREI1_MEMBASE_IMM:
3014 case OP_STOREI2_MEMBASE_IMM:
3015 case OP_STOREI4_MEMBASE_IMM:
3016 case OP_STOREI8_MEMBASE_IMM:
3017 case OP_STORE_MEMBASE_IMM: {
3019 LLVMValueRef index, addr;
3021 gboolean sext = FALSE, zext = FALSE;
3022 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3024 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3026 if (ins->inst_offset % size != 0) {
3027 /* Unaligned store */
3028 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3029 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3031 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3032 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3034 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3039 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3041 case OP_OUTARG_VTRETADDR:
3048 case OP_VOIDCALL_MEMBASE:
3049 case OP_CALL_MEMBASE:
3050 case OP_LCALL_MEMBASE:
3051 case OP_FCALL_MEMBASE:
3052 case OP_VCALL_MEMBASE:
3053 case OP_VOIDCALL_REG:
3057 case OP_VCALL_REG: {
3058 process_call (ctx, bb, &builder, ins);
3059 CHECK_FAILURE (ctx);
3064 LLVMValueRef indexes [2];
3066 LLVMValueRef got_entry_addr;
3069 * FIXME: Can't allocate from the cfg mempool since that is freed if
3070 * the LLVM compile fails.
3072 ji = g_new0 (MonoJumpInfo, 1);
3073 ji->type = (MonoJumpInfoType)ins->inst_i1;
3074 ji->data.target = ins->inst_p0;
3076 ji = mono_aot_patch_info_dup (ji);
3078 ji->next = cfg->patch_info;
3079 cfg->patch_info = ji;
3081 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3082 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3084 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3085 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3086 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3088 // FIXME: This doesn't work right now, because it must be
3089 // paired with an invariant.end, and even then, its only in effect
3090 // inside its basic block
3093 LLVMValueRef args [3];
3094 LLVMValueRef ptr, val;
3096 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3098 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3100 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3104 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3107 case OP_NOT_REACHED:
3108 LLVMBuildUnreachable (builder);
3109 has_terminator = TRUE;
3110 g_assert (bb->block_num < cfg->max_block_num);
3111 ctx->unreachable [bb->block_num] = TRUE;
3112 /* Might have instructions after this */
3114 MonoInst *next = ins->next;
3116 * FIXME: If later code uses the regs defined by these instructions,
3117 * compilation will fail.
3119 MONO_DELETE_INS (bb, next);
3123 MonoInst *var = ins->inst_p0;
3125 values [ins->dreg] = addresses [var->dreg];
3129 LLVMValueRef args [1];
3131 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3132 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3136 LLVMValueRef args [1];
3138 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3139 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3143 LLVMValueRef args [1];
3146 /* This no longer seems to happen */
3148 * LLVM optimizes sqrt(nan) into undefined in
3149 * lib/Analysis/ConstantFolding.cpp
3150 * Also, sqrt(NegativeInfinity) is optimized into 0.
3152 LLVM_FAILURE (ctx, "sqrt");
3154 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3155 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3159 LLVMValueRef args [1];
3161 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3162 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3176 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3177 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3179 switch (ins->opcode) {
3182 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3186 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3190 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3194 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3197 g_assert_not_reached ();
3200 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3203 case OP_ATOMIC_EXCHANGE_I4: {
3204 LLVMValueRef args [2];
3206 g_assert (ins->inst_offset == 0);
3208 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3211 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3214 case OP_ATOMIC_EXCHANGE_I8: {
3215 LLVMValueRef args [2];
3217 g_assert (ins->inst_offset == 0);
3219 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3220 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3221 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3224 case OP_ATOMIC_ADD_NEW_I4: {
3225 LLVMValueRef args [2];
3227 g_assert (ins->inst_offset == 0);
3229 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3231 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3234 case OP_ATOMIC_ADD_NEW_I8: {
3235 LLVMValueRef args [2];
3237 g_assert (ins->inst_offset == 0);
3239 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3240 args [1] = convert (ctx, rhs, LLVMInt64Type ());
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_CAS_I4:
3245 case OP_ATOMIC_CAS_I8: {
3246 LLVMValueRef args [3];
3249 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3250 t = LLVMInt32Type ();
3252 t = LLVMInt64Type ();
3255 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3257 args [1] = convert (ctx, values [ins->sreg3], t);
3259 args [2] = convert (ctx, values [ins->sreg2], t);
3260 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3263 case OP_MEMORY_BARRIER: {
3264 mono_llvm_build_fence (builder);
3267 case OP_RELAXED_NOP: {
3268 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3269 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3276 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3278 // 257 == FS segment register
3279 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3281 // 256 == GS segment register
3282 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3286 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3288 LLVM_FAILURE (ctx, "opcode tls-get");
3298 case OP_IADD_OVF_UN:
3300 case OP_ISUB_OVF_UN:
3302 case OP_IMUL_OVF_UN:
3303 #if SIZEOF_VOID_P == 8
3305 case OP_LADD_OVF_UN:
3307 case OP_LSUB_OVF_UN:
3309 case OP_LMUL_OVF_UN:
3312 LLVMValueRef args [2], val, ovf, func;
3314 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3315 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3316 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3318 val = LLVMBuildCall (builder, func, args, 2, "");
3319 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3320 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3321 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3322 CHECK_FAILURE (ctx);
3323 builder = ctx->builder;
3329 * We currently model them using arrays. Promotion to local vregs is
3330 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3331 * so we always have an entry in cfg->varinfo for them.
3332 * FIXME: Is this needed ?
3335 MonoClass *klass = ins->klass;
3336 LLVMValueRef args [5];
3340 LLVM_FAILURE (ctx, "!klass");
3344 if (!addresses [ins->dreg])
3345 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3346 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3347 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3348 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3350 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3351 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3352 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3356 case OP_STOREV_MEMBASE:
3357 case OP_LOADV_MEMBASE:
3359 MonoClass *klass = ins->klass;
3360 LLVMValueRef src = NULL, dst, args [5];
3361 gboolean done = FALSE;
3365 LLVM_FAILURE (ctx, "!klass");
3369 switch (ins->opcode) {
3370 case OP_STOREV_MEMBASE:
3371 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3372 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3373 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3376 if (!addresses [ins->sreg1]) {
3378 g_assert (values [ins->sreg1]);
3379 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));
3380 LLVMBuildStore (builder, values [ins->sreg1], dst);
3383 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3384 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3387 case OP_LOADV_MEMBASE:
3388 if (!addresses [ins->dreg])
3389 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3390 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3391 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3394 if (!addresses [ins->sreg1])
3395 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3396 if (!addresses [ins->dreg])
3397 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3398 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3399 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3402 g_assert_not_reached ();
3404 CHECK_FAILURE (ctx);
3411 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3412 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3414 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3415 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3416 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3419 case OP_LLVM_OUTARG_VT:
3420 if (!addresses [ins->sreg1]) {
3421 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3422 g_assert (values [ins->sreg1]);
3423 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3425 addresses [ins->dreg] = addresses [ins->sreg1];
3431 #ifdef MONO_ARCH_SIMD_INTRINSICS
3433 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3436 case OP_LOADX_MEMBASE: {
3437 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3440 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3441 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3444 case OP_STOREX_MEMBASE: {
3445 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3448 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3449 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3456 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3460 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3466 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3470 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3474 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3478 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3481 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3484 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3487 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3491 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3502 LLVMValueRef v = NULL;
3504 switch (ins->opcode) {
3509 t = LLVMVectorType (LLVMInt32Type (), 4);
3510 rt = LLVMVectorType (LLVMFloatType (), 4);
3516 t = LLVMVectorType (LLVMInt64Type (), 2);
3517 rt = LLVMVectorType (LLVMDoubleType (), 2);
3520 t = LLVMInt32Type ();
3521 rt = LLVMInt32Type ();
3522 g_assert_not_reached ();
3525 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3526 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3527 switch (ins->opcode) {
3530 v = LLVMBuildAnd (builder, lhs, rhs, "");
3534 v = LLVMBuildOr (builder, lhs, rhs, "");
3538 v = LLVMBuildXor (builder, lhs, rhs, "");
3542 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3545 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3569 case OP_PADDB_SAT_UN:
3570 case OP_PADDW_SAT_UN:
3571 case OP_PSUBB_SAT_UN:
3572 case OP_PSUBW_SAT_UN:
3580 case OP_PMULW_HIGH_UN: {
3581 LLVMValueRef args [2];
3586 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3593 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3597 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3605 case OP_EXTRACTX_U2:
3607 case OP_EXTRACT_U1: {
3609 gboolean zext = FALSE;
3611 t = simd_op_to_llvm_type (ins->opcode);
3613 switch (ins->opcode) {
3621 case OP_EXTRACTX_U2:
3626 t = LLVMInt32Type ();
3627 g_assert_not_reached ();
3630 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3631 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3633 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3642 case OP_EXPAND_R8: {
3643 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3644 LLVMValueRef mask [16], v;
3646 for (i = 0; i < 16; ++i)
3647 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3649 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3651 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3652 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3657 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3660 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3663 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3666 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3669 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3672 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3683 case OP_EXTRACT_MASK:
3690 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3692 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3696 case OP_ICONV_TO_R8_RAW:
3697 /* Same as OP_ICONV_TO_R8 */
3698 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3703 LLVMValueRef args [3];
3707 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3709 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3714 /* This is only used for implementing shifts by non-immediate */
3715 values [ins->dreg] = lhs;
3726 LLVMValueRef args [3];
3729 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3731 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3742 case OP_PSHLQ_REG: {
3743 LLVMValueRef args [3];
3746 args [1] = values [ins->sreg2];
3748 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3755 case OP_PSHUFLEW_LOW:
3756 case OP_PSHUFLEW_HIGH: {
3758 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3759 int i, mask_size = 0;
3760 int imask = ins->inst_c0;
3762 /* Convert the x86 shuffle mask to LLVM's */
3763 switch (ins->opcode) {
3766 mask [0] = ((imask >> 0) & 3);
3767 mask [1] = ((imask >> 2) & 3);
3768 mask [2] = ((imask >> 4) & 3) + 4;
3769 mask [3] = ((imask >> 6) & 3) + 4;
3770 v1 = values [ins->sreg1];
3771 v2 = values [ins->sreg2];
3775 mask [0] = ((imask >> 0) & 1);
3776 mask [1] = ((imask >> 1) & 1) + 2;
3777 v1 = values [ins->sreg1];
3778 v2 = values [ins->sreg2];
3780 case OP_PSHUFLEW_LOW:
3782 mask [0] = ((imask >> 0) & 3);
3783 mask [1] = ((imask >> 2) & 3);
3784 mask [2] = ((imask >> 4) & 3);
3785 mask [3] = ((imask >> 6) & 3);
3790 v1 = values [ins->sreg1];
3791 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3793 case OP_PSHUFLEW_HIGH:
3799 mask [4] = 4 + ((imask >> 0) & 3);
3800 mask [5] = 4 + ((imask >> 2) & 3);
3801 mask [6] = 4 + ((imask >> 4) & 3);
3802 mask [7] = 4 + ((imask >> 6) & 3);
3803 v1 = values [ins->sreg1];
3804 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3808 mask [0] = ((imask >> 0) & 3);
3809 mask [1] = ((imask >> 2) & 3);
3810 mask [2] = ((imask >> 4) & 3);
3811 mask [3] = ((imask >> 6) & 3);
3812 v1 = values [ins->sreg1];
3813 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3816 g_assert_not_reached ();
3818 for (i = 0; i < mask_size; ++i)
3819 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3821 values [ins->dreg] =
3822 LLVMBuildShuffleVector (builder, v1, v2,
3823 LLVMConstVector (mask_values, mask_size), dname);
3827 case OP_UNPACK_LOWB:
3828 case OP_UNPACK_LOWW:
3829 case OP_UNPACK_LOWD:
3830 case OP_UNPACK_LOWQ:
3831 case OP_UNPACK_LOWPS:
3832 case OP_UNPACK_LOWPD:
3833 case OP_UNPACK_HIGHB:
3834 case OP_UNPACK_HIGHW:
3835 case OP_UNPACK_HIGHD:
3836 case OP_UNPACK_HIGHQ:
3837 case OP_UNPACK_HIGHPS:
3838 case OP_UNPACK_HIGHPD: {
3840 LLVMValueRef mask_values [16];
3841 int i, mask_size = 0;
3842 gboolean low = FALSE;
3844 switch (ins->opcode) {
3845 case OP_UNPACK_LOWB:
3849 case OP_UNPACK_LOWW:
3853 case OP_UNPACK_LOWD:
3854 case OP_UNPACK_LOWPS:
3858 case OP_UNPACK_LOWQ:
3859 case OP_UNPACK_LOWPD:
3863 case OP_UNPACK_HIGHB:
3866 case OP_UNPACK_HIGHW:
3869 case OP_UNPACK_HIGHD:
3870 case OP_UNPACK_HIGHPS:
3873 case OP_UNPACK_HIGHQ:
3874 case OP_UNPACK_HIGHPD:
3878 g_assert_not_reached ();
3882 for (i = 0; i < (mask_size / 2); ++i) {
3884 mask [(i * 2) + 1] = mask_size + i;
3887 for (i = 0; i < (mask_size / 2); ++i) {
3888 mask [(i * 2)] = (mask_size / 2) + i;
3889 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3893 for (i = 0; i < mask_size; ++i)
3894 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3896 values [ins->dreg] =
3897 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3898 LLVMConstVector (mask_values, mask_size), dname);
3903 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3904 LLVMValueRef v, val;
3906 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3907 val = LLVMConstNull (t);
3908 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3909 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3911 values [ins->dreg] = val;
3915 case OP_DUPPS_HIGH: {
3916 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3917 LLVMValueRef v1, v2, val;
3920 if (ins->opcode == OP_DUPPS_LOW) {
3921 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3922 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3924 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3925 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3927 val = LLVMConstNull (t);
3928 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3929 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3930 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3931 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3933 values [ins->dreg] = val;
3943 * EXCEPTION HANDLING
3945 case OP_IMPLICIT_EXCEPTION:
3946 /* This marks a place where an implicit exception can happen */
3947 if (bb->region != -1)
3948 LLVM_FAILURE (ctx, "implicit-exception");
3952 MonoMethodSignature *throw_sig;
3953 LLVMValueRef callee, arg;
3954 gboolean rethrow = (ins->opcode == OP_RETHROW);
3955 const char *icall_name;
3957 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3958 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3961 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3962 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3963 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3964 if (cfg->compile_aot) {
3965 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3967 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3971 * LLVM doesn't push the exception argument, so we need a different
3974 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3976 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3980 mono_memory_barrier ();
3982 ctx->lmodule->rethrow = callee;
3984 ctx->lmodule->throw = callee;
3986 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3987 emit_call (ctx, bb, &builder, callee, &arg, 1);
3990 case OP_CALL_HANDLER: {
3992 * We don't 'call' handlers, but instead simply branch to them.
3993 * The code generated by ENDFINALLY will branch back to us.
3995 LLVMBasicBlockRef noex_bb;
3997 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
3999 bb_list = info->call_handler_return_bbs;
4002 * Set the indicator variable for the finally clause.
4004 lhs = info->finally_ind;
4006 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4008 /* Branch to the finally clause */
4009 LLVMBuildBr (builder, info->call_handler_target_bb);
4011 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4012 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4014 builder = ctx->builder = create_builder (ctx);
4015 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4017 bblocks [bb->block_num].end_bblock = noex_bb;
4020 case OP_START_HANDLER: {
4023 case OP_ENDFINALLY: {
4024 LLVMBasicBlockRef resume_bb;
4025 MonoBasicBlock *handler_bb;
4026 LLVMValueRef val, switch_ins, callee;
4030 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4031 g_assert (handler_bb);
4032 info = &bblocks [handler_bb->block_num];
4033 lhs = info->finally_ind;
4036 bb_list = info->call_handler_return_bbs;
4038 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4040 /* Load the finally variable */
4041 val = LLVMBuildLoad (builder, lhs, "");
4043 /* Reset the variable */
4044 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4046 /* Branch to either resume_bb, or to the bblocks in bb_list */
4047 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4049 * The other targets are added at the end to handle OP_CALL_HANDLER
4050 * opcodes processed later.
4052 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4054 builder = ctx->builder = create_builder (ctx);
4055 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4057 if (ctx->cfg->compile_aot) {
4058 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4060 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4062 LLVMBuildCall (builder, callee, NULL, 0, "");
4064 LLVMBuildUnreachable (builder);
4065 has_terminator = TRUE;
4071 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4072 LLVM_FAILURE (ctx, reason);
4077 /* Convert the value to the type required by phi nodes */
4078 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4079 if (!values [ins->dreg])
4081 values [ins->dreg] = addresses [ins->dreg];
4083 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4086 /* Add stores for volatile variables */
4087 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4088 emit_volatile_store (ctx, ins->dreg);
4091 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4092 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4094 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4095 LLVMBuildRetVoid (builder);
4097 if (bb == cfg->bb_entry)
4098 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4107 * mono_llvm_check_method_supported:
4109 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4110 * compiling a method twice.
4113 mono_llvm_check_method_supported (MonoCompile *cfg)
4116 MonoMethodHeader *header = cfg->header;
4117 MonoExceptionClause *clause;
4121 if (cfg->method->save_lmf) {
4122 cfg->exception_message = g_strdup ("lmf");
4123 cfg->disable_llvm = TRUE;
4127 for (i = 0; i < header->num_clauses; ++i) {
4128 clause = &header->clauses [i];
4130 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4132 * FIXME: Some tests still fail with nested clauses.
4134 cfg->exception_message = g_strdup ("nested clauses");
4135 cfg->disable_llvm = TRUE;
4141 if (cfg->method->dynamic) {
4142 cfg->exception_message = g_strdup ("dynamic.");
4143 cfg->disable_llvm = TRUE;
4148 * mono_llvm_emit_method:
4150 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4153 mono_llvm_emit_method (MonoCompile *cfg)
4156 MonoMethodSignature *sig;
4158 LLVMTypeRef method_type;
4159 LLVMValueRef method = NULL;
4161 LLVMValueRef *values;
4162 int i, max_block_num, bb_index;
4163 gboolean last = FALSE;
4164 GPtrArray *phi_values;
4165 LLVMCallInfo *linfo;
4167 LLVMModuleRef module;
4169 GPtrArray *bblock_list;
4170 MonoMethodHeader *header;
4171 MonoExceptionClause *clause;
4175 /* The code below might acquire the loader lock, so use it for global locking */
4176 mono_loader_lock ();
4178 /* Used to communicate with the callbacks */
4179 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4181 ctx = g_new0 (EmitContext, 1);
4183 ctx->mempool = cfg->mempool;
4186 * This maps vregs to the LLVM instruction defining them
4188 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4190 * This maps vregs for volatile variables to the LLVM instruction defining their
4193 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4194 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4195 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4196 phi_values = g_ptr_array_new ();
4198 * This signals whenever the vreg was defined by a phi node with no input vars
4199 * (i.e. all its input bblocks end with NOT_REACHABLE).
4201 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4202 /* Whenever the bblock is unreachable */
4203 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4205 bblock_list = g_ptr_array_new ();
4207 ctx->values = values;
4208 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4210 if (cfg->compile_aot) {
4211 ctx->lmodule = &aot_module;
4212 method_name = mono_aot_get_method_name (cfg);
4213 cfg->llvm_method_name = g_strdup (method_name);
4216 ctx->lmodule = &jit_module;
4217 method_name = mono_method_full_name (cfg->method, TRUE);
4220 module = ctx->module = ctx->lmodule->module;
4224 static int count = 0;
4227 if (getenv ("LLVM_COUNT")) {
4228 if (count == atoi (getenv ("LLVM_COUNT"))) {
4229 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4233 if (count > atoi (getenv ("LLVM_COUNT")))
4234 LLVM_FAILURE (ctx, "");
4239 sig = mono_method_signature (cfg->method);
4242 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4244 CHECK_FAILURE (ctx);
4247 linfo->rgctx_arg = TRUE;
4248 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4249 CHECK_FAILURE (ctx);
4252 * This maps parameter indexes in the original signature to the indexes in
4253 * the LLVM signature.
4255 ctx->pindexes = sinfo.pindexes;
4257 method = LLVMAddFunction (module, method_name, method_type);
4258 ctx->lmethod = method;
4260 #ifdef LLVM_MONO_BRANCH
4261 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4263 LLVMSetLinkage (method, LLVMPrivateLinkage);
4265 LLVMAddFunctionAttr (method, LLVMUWTable);
4267 if (cfg->compile_aot) {
4268 LLVMSetLinkage (method, LLVMInternalLinkage);
4269 LLVMSetVisibility (method, LLVMHiddenVisibility);
4271 LLVMSetLinkage (method, LLVMPrivateLinkage);
4274 if (cfg->method->save_lmf)
4275 LLVM_FAILURE (ctx, "lmf");
4277 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4278 LLVM_FAILURE (ctx, "pinvoke signature");
4280 header = cfg->header;
4281 for (i = 0; i < header->num_clauses; ++i) {
4282 clause = &header->clauses [i];
4283 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4284 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4287 if (linfo->rgctx_arg) {
4288 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4290 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4291 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4292 * CC_X86_64_Mono in X86CallingConv.td.
4294 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4295 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4297 if (cfg->vret_addr) {
4298 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4299 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4302 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4303 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4306 names = g_new (char *, sig->param_count);
4307 mono_method_get_param_names (cfg->method, (const char **) names);
4309 for (i = 0; i < sig->param_count; ++i) {
4312 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4313 if (names [i] && names [i][0] != '\0')
4314 name = g_strdup_printf ("arg_%s", names [i]);
4316 name = g_strdup_printf ("arg_%d", i);
4317 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4319 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4320 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4325 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4326 max_block_num = MAX (max_block_num, bb->block_num);
4327 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4329 /* Add branches between non-consecutive bblocks */
4330 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4331 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4332 bb->next_bb != bb->last_ins->inst_false_bb) {
4334 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4335 inst->opcode = OP_BR;
4336 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4337 mono_bblock_add_inst (bb, inst);
4342 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4343 * was later optimized away, so clear these flags, and add them back for the still
4344 * present OP_LDADDR instructions.
4346 for (i = 0; i < cfg->next_vreg; ++i) {
4349 ins = get_vreg_to_inst (cfg, i);
4350 if (ins && ins != cfg->rgctx_var)
4351 ins->flags &= ~MONO_INST_INDIRECT;
4355 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4357 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4359 LLVMBuilderRef builder;
4361 char dname_buf[128];
4363 builder = create_builder (ctx);
4365 for (ins = bb->code; ins; ins = ins->next) {
4366 switch (ins->opcode) {
4371 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4373 CHECK_FAILURE (ctx);
4375 if (ins->opcode == OP_VPHI) {
4376 /* Treat valuetype PHI nodes as operating on the address itself */
4377 g_assert (ins->klass);
4378 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4382 * Have to precreate these, as they can be referenced by
4383 * earlier instructions.
4385 sprintf (dname_buf, "t%d", ins->dreg);
4387 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4389 if (ins->opcode == OP_VPHI)
4390 ctx->addresses [ins->dreg] = values [ins->dreg];
4392 g_ptr_array_add (phi_values, values [ins->dreg]);
4395 * Set the expected type of the incoming arguments since these have
4396 * to have the same type.
4398 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4399 int sreg1 = ins->inst_phi_args [i + 1];
4402 ctx->vreg_types [sreg1] = phi_type;
4407 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4416 * Create an ordering for bblocks, use the depth first order first, then
4417 * put the exception handling bblocks last.
4419 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4420 bb = cfg->bblocks [bb_index];
4421 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4422 g_ptr_array_add (bblock_list, bb);
4423 bblocks [bb->block_num].added = TRUE;
4427 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4428 if (!bblocks [bb->block_num].added)
4429 g_ptr_array_add (bblock_list, bb);
4433 * Second pass: generate code.
4435 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4436 bb = g_ptr_array_index (bblock_list, bb_index);
4438 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4441 process_bb (ctx, bb);
4442 CHECK_FAILURE (ctx);
4445 /* Add incoming phi values */
4446 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4447 GSList *l, *ins_list;
4449 ins_list = bblocks [bb->block_num].phi_nodes;
4451 for (l = ins_list; l; l = l->next) {
4452 PhiNode *node = l->data;
4453 MonoInst *phi = node->phi;
4454 int sreg1 = node->sreg;
4455 LLVMBasicBlockRef in_bb;
4460 in_bb = get_end_bb (ctx, node->in_bb);
4462 if (ctx->unreachable [node->in_bb->block_num])
4465 if (!values [sreg1])
4466 /* Can happen with values in EH clauses */
4467 LLVM_FAILURE (ctx, "incoming phi sreg1");
4469 if (phi->opcode == OP_VPHI) {
4470 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4471 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4473 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4474 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4479 /* Create the SWITCH statements for ENDFINALLY instructions */
4480 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4481 BBInfo *info = &bblocks [bb->block_num];
4483 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4484 LLVMValueRef switch_ins = l->data;
4485 GSList *bb_list = info->call_handler_return_bbs;
4487 for (i = 0; i < g_slist_length (bb_list); ++i)
4488 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4492 if (cfg->verbose_level > 1)
4493 mono_llvm_dump_value (method);
4495 mark_as_used (module, method);
4497 if (cfg->compile_aot) {
4498 /* Don't generate native code, keep the LLVM IR */
4499 if (cfg->compile_aot && cfg->verbose_level)
4500 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4502 //LLVMVerifyFunction(method, 0);
4504 mono_llvm_optimize_method (method);
4506 if (cfg->verbose_level > 1)
4507 mono_llvm_dump_value (method);
4509 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4511 /* Set by emit_cb */
4512 g_assert (cfg->code_len);
4514 /* FIXME: Free the LLVM IL for the function */
4522 /* Need to add unused phi nodes as they can be referenced by other values */
4523 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4524 LLVMBuilderRef builder;
4526 builder = create_builder (ctx);
4527 LLVMPositionBuilderAtEnd (builder, phi_bb);
4529 for (i = 0; i < phi_values->len; ++i) {
4530 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4531 if (LLVMGetInstructionParent (v) == NULL)
4532 LLVMInsertIntoBuilder (builder, v);
4535 LLVMDeleteFunction (method);
4540 g_free (ctx->addresses);
4541 g_free (ctx->vreg_types);
4542 g_free (ctx->vreg_cli_types);
4543 g_free (ctx->pindexes);
4544 g_free (ctx->is_dead);
4545 g_free (ctx->unreachable);
4546 g_ptr_array_free (phi_values, TRUE);
4547 g_free (ctx->bblocks);
4548 g_hash_table_destroy (ctx->region_to_handler);
4549 g_free (method_name);
4550 g_ptr_array_free (bblock_list, TRUE);
4552 for (l = ctx->builders; l; l = l->next) {
4553 LLVMBuilderRef builder = l->data;
4554 LLVMDisposeBuilder (builder);
4559 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4561 mono_loader_unlock ();
4565 * mono_llvm_emit_call:
4567 * Same as mono_arch_emit_call () for LLVM.
4570 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4573 MonoMethodSignature *sig;
4574 int i, n, stack_size;
4579 sig = call->signature;
4580 n = sig->param_count + sig->hasthis;
4582 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4584 if (cfg->disable_llvm)
4587 if (sig->call_convention == MONO_CALL_VARARG) {
4588 cfg->exception_message = g_strdup ("varargs");
4589 cfg->disable_llvm = TRUE;
4592 for (i = 0; i < n; ++i) {
4595 ainfo = call->cinfo->args + i;
4597 in = call->args [i];
4599 /* Simply remember the arguments */
4600 switch (ainfo->storage) {
4602 case LLVMArgInFPReg: {
4603 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4605 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4606 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4607 ins->dreg = mono_alloc_freg (cfg);
4609 MONO_INST_NEW (cfg, ins, OP_MOVE);
4610 ins->dreg = mono_alloc_ireg (cfg);
4612 ins->sreg1 = in->dreg;
4615 case LLVMArgVtypeByVal:
4616 case LLVMArgVtypeInReg:
4617 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4618 ins->dreg = mono_alloc_ireg (cfg);
4619 ins->sreg1 = in->dreg;
4620 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4623 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4624 cfg->exception_message = g_strdup ("ainfo->storage");
4625 cfg->disable_llvm = TRUE;
4629 if (!cfg->disable_llvm) {
4630 MONO_ADD_INS (cfg->cbb, ins);
4631 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4636 static unsigned char*
4637 alloc_cb (LLVMValueRef function, int size)
4641 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4645 return mono_domain_code_reserve (cfg->domain, size);
4647 return mono_domain_code_reserve (mono_domain_get (), size);
4652 emitted_cb (LLVMValueRef function, void *start, void *end)
4656 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4658 cfg->code_len = (guint8*)end - (guint8*)start;
4662 exception_cb (void *data)
4665 MonoJitExceptionInfo *ei;
4666 guint32 ei_len, i, j, nested_len, nindex;
4667 gpointer *type_info;
4668 int this_reg, this_offset;
4670 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4674 * data points to a DWARF FDE structure, convert it to our unwind format and
4676 * An alternative would be to save it directly, and modify our unwinder to work
4679 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);
4681 /* Count nested clauses */
4683 for (i = 0; i < ei_len; ++i) {
4684 for (j = 0; j < ei_len; ++j) {
4685 gint32 cindex1 = *(gint32*)type_info [i];
4686 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4687 gint32 cindex2 = *(gint32*)type_info [j];
4688 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4690 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4696 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4697 cfg->llvm_ex_info_len = ei_len + nested_len;
4698 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4699 /* Fill the rest of the information from the type info */
4700 for (i = 0; i < ei_len; ++i) {
4701 gint32 clause_index = *(gint32*)type_info [i];
4702 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4704 cfg->llvm_ex_info [i].flags = clause->flags;
4705 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4709 * For nested clauses, the LLVM produced exception info associates the try interval with
4710 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4712 /* FIXME: These should be order with the normal clauses */
4714 for (i = 0; i < ei_len; ++i) {
4715 for (j = 0; j < ei_len; ++j) {
4716 gint32 cindex1 = *(gint32*)type_info [i];
4717 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4718 gint32 cindex2 = *(gint32*)type_info [j];
4719 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4721 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4723 * The try interval comes from the nested clause, everything else from the
4726 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4727 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4728 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4733 g_assert (nindex == ei_len + nested_len);
4734 cfg->llvm_this_reg = this_reg;
4735 cfg->llvm_this_offset = this_offset;
4737 /* type_info [i] is cfg mempool allocated, no need to free it */
4744 dlsym_cb (const char *name, void **symbol)
4748 current = mono_dl_open (NULL, 0, NULL);
4751 return mono_dl_symbol (current, name, symbol);
4755 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4757 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4761 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4763 LLVMTypeRef param_types [4];
4765 param_types [0] = param_type1;
4766 param_types [1] = param_type2;
4768 AddFunc (module, name, ret_type, param_types, 2);
4772 add_intrinsics (LLVMModuleRef module)
4774 /* Emit declarations of instrinsics */
4776 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4777 * type doesn't seem to do any locking.
4780 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4782 memset_param_count = 5;
4783 memset_func_name = "llvm.memset.p0i8.i32";
4785 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4789 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4791 memcpy_param_count = 5;
4792 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4794 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4798 LLVMTypeRef params [] = { LLVMDoubleType () };
4800 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4801 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4802 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4804 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4805 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4809 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4810 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4812 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4813 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4814 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4815 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4816 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4817 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4821 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4822 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4824 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4825 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4826 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4827 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4828 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4829 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4833 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4834 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4835 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4837 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4839 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4844 LLVMTypeRef arg_types [2];
4845 LLVMTypeRef ret_type;
4847 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4848 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4849 ret_type = LLVMInt32Type ();
4851 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4853 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4856 /* SSE intrinsics */
4858 LLVMTypeRef ret_type, arg_types [16];
4861 ret_type = type_to_simd_type (MONO_TYPE_I4);
4862 arg_types [0] = ret_type;
4863 arg_types [1] = ret_type;
4864 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4865 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4867 ret_type = type_to_simd_type (MONO_TYPE_I2);
4868 arg_types [0] = ret_type;
4869 arg_types [1] = ret_type;
4870 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4871 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4872 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4873 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4874 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4875 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4876 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4877 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4878 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4879 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4881 ret_type = type_to_simd_type (MONO_TYPE_I1);
4882 arg_types [0] = ret_type;
4883 arg_types [1] = ret_type;
4884 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4885 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4886 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4887 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4888 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4889 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4890 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4892 ret_type = type_to_simd_type (MONO_TYPE_R8);
4893 arg_types [0] = ret_type;
4894 arg_types [1] = ret_type;
4895 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4896 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4897 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4898 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4899 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4901 ret_type = type_to_simd_type (MONO_TYPE_R4);
4902 arg_types [0] = ret_type;
4903 arg_types [1] = ret_type;
4904 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4905 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4906 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4907 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4908 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4911 ret_type = type_to_simd_type (MONO_TYPE_I1);
4912 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4913 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4914 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4915 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4916 ret_type = type_to_simd_type (MONO_TYPE_I2);
4917 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4918 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4919 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4920 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4923 ret_type = type_to_simd_type (MONO_TYPE_R8);
4924 arg_types [0] = ret_type;
4925 arg_types [1] = ret_type;
4926 arg_types [2] = LLVMInt8Type ();
4927 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4928 ret_type = type_to_simd_type (MONO_TYPE_R4);
4929 arg_types [0] = ret_type;
4930 arg_types [1] = ret_type;
4931 arg_types [2] = LLVMInt8Type ();
4932 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4934 /* Conversion ops */
4935 ret_type = type_to_simd_type (MONO_TYPE_R8);
4936 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4937 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4938 ret_type = type_to_simd_type (MONO_TYPE_R4);
4939 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4940 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4941 ret_type = type_to_simd_type (MONO_TYPE_I4);
4942 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4943 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4944 ret_type = type_to_simd_type (MONO_TYPE_I4);
4945 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4946 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4947 ret_type = type_to_simd_type (MONO_TYPE_R4);
4948 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4949 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4950 ret_type = type_to_simd_type (MONO_TYPE_R8);
4951 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4952 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4954 ret_type = type_to_simd_type (MONO_TYPE_I4);
4955 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4956 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4957 ret_type = type_to_simd_type (MONO_TYPE_I4);
4958 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4959 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4962 ret_type = type_to_simd_type (MONO_TYPE_R8);
4963 arg_types [0] = ret_type;
4964 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
4965 ret_type = type_to_simd_type (MONO_TYPE_R4);
4966 arg_types [0] = ret_type;
4967 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
4968 ret_type = type_to_simd_type (MONO_TYPE_R4);
4969 arg_types [0] = ret_type;
4970 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
4971 ret_type = type_to_simd_type (MONO_TYPE_R4);
4972 arg_types [0] = ret_type;
4973 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
4976 ret_type = type_to_simd_type (MONO_TYPE_I2);
4977 arg_types [0] = ret_type;
4978 arg_types [1] = LLVMInt32Type ();
4979 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
4980 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
4981 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
4982 ret_type = type_to_simd_type (MONO_TYPE_I4);
4983 arg_types [0] = ret_type;
4984 arg_types [1] = LLVMInt32Type ();
4985 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
4986 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
4987 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
4988 ret_type = type_to_simd_type (MONO_TYPE_I8);
4989 arg_types [0] = ret_type;
4990 arg_types [1] = LLVMInt32Type ();
4991 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
4992 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
4995 ret_type = LLVMInt32Type ();
4996 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
4997 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5000 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5002 /* Load/Store intrinsics */
5004 LLVMTypeRef arg_types [5];
5008 for (i = 1; i <= 8; i *= 2) {
5009 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5010 arg_types [1] = LLVMInt32Type ();
5011 arg_types [2] = LLVMInt1Type ();
5012 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5013 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5015 arg_types [0] = LLVMIntType (i * 8);
5016 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5017 arg_types [2] = LLVMInt32Type ();
5018 arg_types [3] = LLVMInt1Type ();
5019 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5020 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5026 mono_llvm_init (void)
5028 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5032 init_jit_module (void)
5034 MonoJitICallInfo *info;
5036 if (jit_module_inited)
5039 mono_loader_lock ();
5041 if (jit_module_inited) {
5042 mono_loader_unlock ();
5046 jit_module.module = LLVMModuleCreateWithName ("mono");
5048 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5050 add_intrinsics (jit_module.module);
5052 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5054 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5056 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5058 jit_module_inited = TRUE;
5060 mono_loader_unlock ();
5064 mono_llvm_cleanup (void)
5067 mono_llvm_dispose_ee (ee);
5069 if (jit_module.llvm_types)
5070 g_hash_table_destroy (jit_module.llvm_types);
5072 if (aot_module.module)
5073 LLVMDisposeModule (aot_module.module);
5075 LLVMContextDispose (LLVMGetGlobalContext ());
5079 mono_llvm_create_aot_module (const char *got_symbol)
5081 /* Delete previous module */
5082 if (aot_module.plt_entries)
5083 g_hash_table_destroy (aot_module.plt_entries);
5084 if (aot_module.module)
5085 LLVMDisposeModule (aot_module.module);
5087 memset (&aot_module, 0, sizeof (aot_module));
5089 aot_module.module = LLVMModuleCreateWithName ("aot");
5090 aot_module.got_symbol = got_symbol;
5092 add_intrinsics (aot_module.module);
5096 * We couldn't compute the type of the LLVM global representing the got because
5097 * its size is only known after all the methods have been emitted. So create
5098 * a dummy variable, and replace all uses it with the real got variable when
5099 * its size is known in mono_llvm_emit_aot_module ().
5102 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5104 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5105 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5108 /* Add a dummy personality function */
5110 LLVMBasicBlockRef lbb;
5111 LLVMBuilderRef lbuilder;
5112 LLVMValueRef personality;
5114 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5115 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5116 lbb = LLVMAppendBasicBlock (personality, "BB0");
5117 lbuilder = LLVMCreateBuilder ();
5118 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5119 LLVMBuildRetVoid (lbuilder);
5122 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5123 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5127 * Emit the aot module into the LLVM bitcode file FILENAME.
5130 mono_llvm_emit_aot_module (const char *filename, int got_size)
5132 LLVMTypeRef got_type;
5133 LLVMValueRef real_got;
5136 * Create the real got variable and replace all uses of the dummy variable with
5139 got_type = LLVMArrayType (IntPtrType (), got_size);
5140 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5141 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5142 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5144 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5146 mark_as_used (aot_module.module, real_got);
5148 /* Delete the dummy got so it doesn't become a global */
5149 LLVMDeleteGlobal (aot_module.got_var);
5155 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5156 g_assert_not_reached ();
5161 LLVMWriteBitcodeToFile (aot_module.module, filename);
5166 - Emit LLVM IR from the mono IR using the LLVM C API.
5167 - The original arch specific code remains, so we can fall back to it if we run
5168 into something we can't handle.
5172 A partial list of issues:
5173 - Handling of opcodes which can throw exceptions.
5175 In the mono JIT, these are implemented using code like this:
5182 push throw_pos - method
5183 call <exception trampoline>
5185 The problematic part is push throw_pos - method, which cannot be represented
5186 in the LLVM IR, since it does not support label values.
5187 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5188 be implemented in JIT mode ?
5189 -> a possible but slower implementation would use the normal exception
5190 throwing code but it would need to control the placement of the throw code
5191 (it needs to be exactly after the compare+branch).
5192 -> perhaps add a PC offset intrinsics ?
5194 - efficient implementation of .ovf opcodes.
5196 These are currently implemented as:
5197 <ins which sets the condition codes>
5200 Some overflow opcodes are now supported by LLVM SVN.
5202 - exception handling, unwinding.
5203 - SSA is disabled for methods with exception handlers
5204 - How to obtain unwind info for LLVM compiled methods ?
5205 -> this is now solved by converting the unwind info generated by LLVM
5207 - LLVM uses the c++ exception handling framework, while we use our home grown
5208 code, and couldn't use the c++ one:
5209 - its not supported under VC++, other exotic platforms.
5210 - it might be impossible to support filter clauses with it.
5214 The trampolines need a predictable call sequence, since they need to disasm
5215 the calling code to obtain register numbers / offsets.
5217 LLVM currently generates this code in non-JIT mode:
5218 mov -0x98(%rax),%eax
5220 Here, the vtable pointer is lost.
5221 -> solution: use one vtable trampoline per class.
5223 - passing/receiving the IMT pointer/RGCTX.
5224 -> solution: pass them as normal arguments ?
5228 LLVM does not allow the specification of argument registers etc. This means
5229 that all calls are made according to the platform ABI.
5231 - passing/receiving vtypes.
5233 Vtypes passed/received in registers are handled by the front end by using
5234 a signature with scalar arguments, and loading the parts of the vtype into those
5237 Vtypes passed on the stack are handled using the 'byval' attribute.
5241 Supported though alloca, we need to emit the load/store code.
5245 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5246 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5247 This is made easier because the IR is already in SSA form.
5248 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5249 types are frequently used incorrectly.
5254 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5255 append the AOT data structures to that file. For methods which cannot be
5256 handled by LLVM, the normal JIT compiled versions are used.
5259 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5260 * - each bblock should end with a branch
5261 * - setting the return value, making cfg->ret non-volatile
5262 * - avoid some transformations in the JIT which make it harder for us to generate
5264 * - use pointer types to help optimizations.