2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
33 LLVMValueRef throw, rethrow, throw_corlib_exception;
34 GHashTable *llvm_types;
36 const char *got_symbol;
37 GHashTable *plt_entries;
41 * Information associated by the backend with mono basic blocks.
44 LLVMBasicBlockRef bblock, end_bblock;
45 LLVMValueRef finally_ind;
46 gboolean added, invoke_target;
48 * If this bblock is the start of a finally clause, this is a list of bblocks it
49 * needs to branch to in ENDFINALLY.
51 GSList *call_handler_return_bbs;
53 * If this bblock is the start of a finally clause, this is the bblock that
54 * CALL_HANDLER needs to branch to.
56 LLVMBasicBlockRef call_handler_target_bb;
57 /* The list of switch statements generated by ENDFINALLY instructions */
58 GSList *endfinally_switch_ins_list;
63 * Structure containing emit state
68 /* Maps method names to the corresponding LLVMValueRef */
69 GHashTable *emitted_method_decls;
73 MonoLLVMModule *lmodule;
76 int sindex, default_index, ex_index;
77 LLVMBuilderRef builder;
78 LLVMValueRef *values, *addresses;
79 MonoType **vreg_cli_types;
81 MonoMethodSignature *sig;
83 GHashTable *region_to_handler;
84 LLVMBuilderRef alloca_builder;
85 LLVMValueRef last_alloca;
86 LLVMValueRef rgctx_arg;
87 LLVMTypeRef *vreg_types;
89 gboolean *unreachable;
98 MonoBasicBlock *in_bb;
103 * Instruction metadata
104 * This is the same as ins_info, but LREG != IREG.
112 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
113 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
120 /* keep in sync with the enum in mini.h */
123 #include "mini-ops.h"
128 #if SIZEOF_VOID_P == 4
129 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
131 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
134 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
137 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
139 #define TRACE_FAILURE(msg)
143 #define IS_TARGET_X86 1
145 #define IS_TARGET_X86 0
148 #define LLVM_FAILURE(ctx, reason) do { \
149 TRACE_FAILURE (reason); \
150 (ctx)->cfg->exception_message = g_strdup (reason); \
151 (ctx)->cfg->disable_llvm = TRUE; \
155 #define CHECK_FAILURE(ctx) do { \
156 if ((ctx)->cfg->disable_llvm) \
160 static LLVMIntPredicate cond_to_llvm_cond [] = {
173 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
186 static LLVMExecutionEngineRef ee;
187 static MonoNativeTlsKey current_cfg_tls_id;
189 static MonoLLVMModule jit_module, aot_module;
190 static gboolean jit_module_inited;
191 static int memset_param_count, memcpy_param_count;
192 static const char *memset_func_name;
193 static const char *memcpy_func_name;
195 static void init_jit_module (void);
200 * The LLVM type with width == sizeof (gpointer)
205 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
211 * Return the size of the LLVM representation of the vtype T.
214 get_vtype_size (MonoType *t)
218 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
220 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
227 * simd_class_to_llvm_type:
229 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
232 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
234 if (!strcmp (klass->name, "Vector2d")) {
235 return LLVMVectorType (LLVMDoubleType (), 2);
236 } else if (!strcmp (klass->name, "Vector2l")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector2ul")) {
239 return LLVMVectorType (LLVMInt64Type (), 2);
240 } else if (!strcmp (klass->name, "Vector4i")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4ui")) {
243 return LLVMVectorType (LLVMInt32Type (), 4);
244 } else if (!strcmp (klass->name, "Vector4f")) {
245 return LLVMVectorType (LLVMFloatType (), 4);
246 } else if (!strcmp (klass->name, "Vector8s")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector8us")) {
249 return LLVMVectorType (LLVMInt16Type (), 8);
250 } else if (!strcmp (klass->name, "Vector16sb")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else if (!strcmp (klass->name, "Vector16b")) {
253 return LLVMVectorType (LLVMInt8Type (), 16);
255 printf ("%s\n", klass->name);
261 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
262 static inline G_GNUC_UNUSED LLVMTypeRef
263 type_to_simd_type (int type)
267 return LLVMVectorType (LLVMInt8Type (), 16);
269 return LLVMVectorType (LLVMInt16Type (), 8);
271 return LLVMVectorType (LLVMInt32Type (), 4);
273 return LLVMVectorType (LLVMInt64Type (), 2);
275 return LLVMVectorType (LLVMDoubleType (), 2);
277 return LLVMVectorType (LLVMFloatType (), 4);
279 g_assert_not_reached ();
287 * Return the LLVM type corresponding to T.
290 type_to_llvm_type (EmitContext *ctx, MonoType *t)
293 return LLVMPointerType (LLVMInt8Type (), 0);
296 return LLVMVoidType ();
298 return LLVMInt8Type ();
300 return LLVMInt16Type ();
302 return LLVMInt32Type ();
304 return LLVMInt8Type ();
306 return LLVMInt16Type ();
308 return LLVMInt32Type ();
309 case MONO_TYPE_BOOLEAN:
310 return LLVMInt8Type ();
313 return LLVMInt64Type ();
315 return LLVMInt16Type ();
317 return LLVMFloatType ();
319 return LLVMDoubleType ();
322 return IntPtrType ();
323 case MONO_TYPE_OBJECT:
324 case MONO_TYPE_CLASS:
325 case MONO_TYPE_ARRAY:
326 case MONO_TYPE_SZARRAY:
327 case MONO_TYPE_STRING:
329 return IntPtrType ();
332 /* Because of generic sharing */
333 return IntPtrType ();
334 case MONO_TYPE_GENERICINST:
335 if (!mono_type_generic_inst_is_valuetype (t))
336 return IntPtrType ();
338 case MONO_TYPE_VALUETYPE:
339 case MONO_TYPE_TYPEDBYREF: {
343 klass = mono_class_from_mono_type (t);
345 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
346 return simd_class_to_llvm_type (ctx, klass);
349 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
350 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
353 LLVMTypeRef *eltypes;
356 size = get_vtype_size (t);
358 eltypes = g_new (LLVMTypeRef, size);
359 for (i = 0; i < size; ++i)
360 eltypes [i] = LLVMInt8Type ();
362 name = mono_type_full_name (&klass->byval_arg);
363 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
364 LLVMStructSetBody (ltype, eltypes, size, FALSE);
365 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
372 printf ("X: %d\n", t->type);
373 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
374 ctx->cfg->disable_llvm = TRUE;
382 * Return whenever T is an unsigned int type.
385 type_is_unsigned (EmitContext *ctx, MonoType *t)
401 * type_to_llvm_arg_type:
403 * Same as type_to_llvm_type, but treat i8/i16 as i32.
406 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
408 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
410 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
412 * LLVM generates code which only sets the lower bits, while JITted
413 * code expects all the bits to be set.
415 ptype = LLVMInt32Type ();
422 * llvm_type_to_stack_type:
424 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
427 static G_GNUC_UNUSED LLVMTypeRef
428 llvm_type_to_stack_type (LLVMTypeRef type)
432 if (type == LLVMInt8Type ())
433 return LLVMInt32Type ();
434 else if (type == LLVMInt16Type ())
435 return LLVMInt32Type ();
436 else if (type == LLVMFloatType ())
437 return LLVMDoubleType ();
443 * regtype_to_llvm_type:
445 * Return the LLVM type corresponding to the regtype C used in instruction
449 regtype_to_llvm_type (char c)
453 return LLVMInt32Type ();
455 return LLVMInt64Type ();
457 return LLVMDoubleType ();
466 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
469 op_to_llvm_type (int opcode)
474 return LLVMInt8Type ();
477 return LLVMInt8Type ();
480 return LLVMInt16Type ();
483 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt32Type ();
491 return LLVMInt64Type ();
493 return LLVMFloatType ();
495 return LLVMDoubleType ();
497 return LLVMInt64Type ();
499 return LLVMInt32Type ();
501 return LLVMInt64Type ();
504 return LLVMInt8Type ();
507 return LLVMInt16Type ();
510 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
517 return LLVMInt32Type ();
524 return LLVMInt64Type ();
526 printf ("%s\n", mono_inst_name (opcode));
527 g_assert_not_reached ();
533 * load_store_to_llvm_type:
535 * Return the size/sign/zero extension corresponding to the load/store opcode
539 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
545 case OP_LOADI1_MEMBASE:
546 case OP_STOREI1_MEMBASE_REG:
547 case OP_STOREI1_MEMBASE_IMM:
550 return LLVMInt8Type ();
551 case OP_LOADU1_MEMBASE:
555 return LLVMInt8Type ();
556 case OP_LOADI2_MEMBASE:
557 case OP_STOREI2_MEMBASE_REG:
558 case OP_STOREI2_MEMBASE_IMM:
561 return LLVMInt16Type ();
562 case OP_LOADU2_MEMBASE:
566 return LLVMInt16Type ();
567 case OP_LOADI4_MEMBASE:
568 case OP_LOADU4_MEMBASE:
571 case OP_STOREI4_MEMBASE_REG:
572 case OP_STOREI4_MEMBASE_IMM:
574 return LLVMInt32Type ();
575 case OP_LOADI8_MEMBASE:
577 case OP_STOREI8_MEMBASE_REG:
578 case OP_STOREI8_MEMBASE_IMM:
580 return LLVMInt64Type ();
581 case OP_LOADR4_MEMBASE:
582 case OP_STORER4_MEMBASE_REG:
584 return LLVMFloatType ();
585 case OP_LOADR8_MEMBASE:
586 case OP_STORER8_MEMBASE_REG:
588 return LLVMDoubleType ();
589 case OP_LOAD_MEMBASE:
591 case OP_STORE_MEMBASE_REG:
592 case OP_STORE_MEMBASE_IMM:
593 *size = sizeof (gpointer);
594 return IntPtrType ();
596 g_assert_not_reached ();
604 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
607 ovf_op_to_intrins (int opcode)
611 return "llvm.sadd.with.overflow.i32";
613 return "llvm.uadd.with.overflow.i32";
615 return "llvm.ssub.with.overflow.i32";
617 return "llvm.usub.with.overflow.i32";
619 return "llvm.smul.with.overflow.i32";
621 return "llvm.umul.with.overflow.i32";
623 return "llvm.sadd.with.overflow.i64";
625 return "llvm.uadd.with.overflow.i64";
627 return "llvm.ssub.with.overflow.i64";
629 return "llvm.usub.with.overflow.i64";
631 return "llvm.smul.with.overflow.i64";
633 return "llvm.umul.with.overflow.i64";
635 g_assert_not_reached ();
641 simd_op_to_intrins (int opcode)
644 #if defined(TARGET_X86) || defined(TARGET_AMD64)
646 return "llvm.x86.sse2.min.pd";
648 return "llvm.x86.sse.min.ps";
650 return "llvm.x86.sse41.pminud";
652 return "llvm.x86.sse41.pminuw";
654 return "llvm.x86.sse2.pminu.b";
656 return "llvm.x86.sse2.pmins.w";
658 return "llvm.x86.sse2.max.pd";
660 return "llvm.x86.sse.max.ps";
662 return "llvm.x86.sse3.hadd.pd";
664 return "llvm.x86.sse3.hadd.ps";
666 return "llvm.x86.sse3.hsub.pd";
668 return "llvm.x86.sse3.hsub.ps";
670 return "llvm.x86.sse41.pmaxud";
672 return "llvm.x86.sse41.pmaxuw";
674 return "llvm.x86.sse2.pmaxu.b";
676 return "llvm.x86.sse3.addsub.ps";
678 return "llvm.x86.sse3.addsub.pd";
679 case OP_EXTRACT_MASK:
680 return "llvm.x86.sse2.pmovmskb.128";
683 return "llvm.x86.sse2.psrli.w";
686 return "llvm.x86.sse2.psrli.d";
689 return "llvm.x86.sse2.psrli.q";
692 return "llvm.x86.sse2.pslli.w";
695 return "llvm.x86.sse2.pslli.d";
698 return "llvm.x86.sse2.pslli.q";
701 return "llvm.x86.sse2.psrai.w";
704 return "llvm.x86.sse2.psrai.d";
706 return "llvm.x86.sse2.padds.b";
708 return "llvm.x86.sse2.padds.w";
710 return "llvm.x86.sse2.psubs.b";
712 return "llvm.x86.sse2.psubs.w";
713 case OP_PADDB_SAT_UN:
714 return "llvm.x86.sse2.paddus.b";
715 case OP_PADDW_SAT_UN:
716 return "llvm.x86.sse2.paddus.w";
717 case OP_PSUBB_SAT_UN:
718 return "llvm.x86.sse2.psubus.b";
719 case OP_PSUBW_SAT_UN:
720 return "llvm.x86.sse2.psubus.w";
722 return "llvm.x86.sse2.pavg.b";
724 return "llvm.x86.sse2.pavg.w";
726 return "llvm.x86.sse.sqrt.ps";
728 return "llvm.x86.sse2.sqrt.pd";
730 return "llvm.x86.sse.rsqrt.ps";
732 return "llvm.x86.sse.rcp.ps";
734 return "llvm.x86.sse2.cvtdq2pd";
736 return "llvm.x86.sse2.cvtdq2ps";
738 return "llvm.x86.sse2.cvtpd2dq";
740 return "llvm.x86.sse2.cvtps2dq";
742 return "llvm.x86.sse2.cvtpd2ps";
744 return "llvm.x86.sse2.cvtps2pd";
746 return "llvm.x86.sse2.cvttpd2dq";
748 return "llvm.x86.sse2.cvttps2dq";
750 return "llvm.x86.sse.cmp.ps";
752 return "llvm.x86.sse2.cmp.pd";
754 return "llvm.x86.sse2.packsswb.128";
756 return "llvm.x86.sse2.packssdw.128";
758 return "llvm.x86.sse2.packuswb.128";
760 return "llvm.x86.sse41.packusdw";
762 return "llvm.x86.sse2.pmulh.w";
763 case OP_PMULW_HIGH_UN:
764 return "llvm.x86.sse2.pmulhu.w";
767 g_assert_not_reached ();
773 simd_op_to_llvm_type (int opcode)
775 #if defined(TARGET_X86) || defined(TARGET_AMD64)
779 return type_to_simd_type (MONO_TYPE_R8);
782 return type_to_simd_type (MONO_TYPE_I8);
785 return type_to_simd_type (MONO_TYPE_I4);
790 return type_to_simd_type (MONO_TYPE_I2);
794 return type_to_simd_type (MONO_TYPE_I1);
796 return type_to_simd_type (MONO_TYPE_R4);
799 return type_to_simd_type (MONO_TYPE_I4);
803 return type_to_simd_type (MONO_TYPE_R8);
807 return type_to_simd_type (MONO_TYPE_R4);
808 case OP_EXTRACT_MASK:
809 return type_to_simd_type (MONO_TYPE_I1);
815 return type_to_simd_type (MONO_TYPE_R4);
818 return type_to_simd_type (MONO_TYPE_R8);
820 g_assert_not_reached ();
831 * Return the LLVM basic block corresponding to BB.
833 static LLVMBasicBlockRef
834 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
838 if (ctx->bblocks [bb->block_num].bblock == NULL) {
839 if (bb->flags & BB_EXCEPTION_HANDLER) {
840 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
841 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
843 sprintf (bb_name, "BB%d", bb->block_num);
846 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
847 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
850 return ctx->bblocks [bb->block_num].bblock;
856 * Return the last LLVM bblock corresponding to BB.
857 * This might not be equal to the bb returned by get_bb () since we need to generate
858 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
860 static LLVMBasicBlockRef
861 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
864 return ctx->bblocks [bb->block_num].end_bblock;
867 static LLVMBasicBlockRef
868 gen_bb (EmitContext *ctx, const char *prefix)
872 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
873 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
879 * Return the target of the patch identified by TYPE and TARGET.
882 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
886 memset (&ji, 0, sizeof (ji));
888 ji.data.target = target;
890 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
896 * Emit code to convert the LLVM value V to DTYPE.
899 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
901 LLVMTypeRef stype = LLVMTypeOf (v);
903 if (stype != dtype) {
904 gboolean ext = FALSE;
907 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
909 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
911 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
915 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
917 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
918 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
921 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
922 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
923 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
924 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
925 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
926 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
927 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
928 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
930 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
931 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
932 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
933 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
934 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
935 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
937 if (mono_arch_is_soft_float ()) {
938 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
939 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
940 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
941 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
944 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
945 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
948 LLVMDumpValue (LLVMConstNull (dtype));
949 g_assert_not_reached ();
957 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
959 return convert_full (ctx, v, dtype, FALSE);
963 * emit_volatile_load:
965 * If vreg is volatile, emit a load from its address.
968 emit_volatile_load (EmitContext *ctx, int vreg)
972 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
973 t = ctx->vreg_cli_types [vreg];
974 if (t && !t->byref) {
976 * Might have to zero extend since llvm doesn't have
979 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
980 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
981 else if (t->type == MONO_TYPE_U8)
982 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
989 * emit_volatile_store:
991 * If VREG is volatile, emit a store from its value to its address.
994 emit_volatile_store (EmitContext *ctx, int vreg)
996 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
998 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
999 g_assert (ctx->addresses [vreg]);
1000 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1006 * Maps parameter indexes in the original signature to parameter indexes
1007 * in the LLVM signature.
1010 /* The indexes of various special arguments in the LLVM signature */
1011 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1015 * sig_to_llvm_sig_full:
1017 * Return the LLVM signature corresponding to the mono signature SIG using the
1018 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1021 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1024 LLVMTypeRef ret_type;
1025 LLVMTypeRef *param_types = NULL;
1027 int i, j, pindex, vret_arg_pindex = 0;
1029 gboolean vretaddr = FALSE;
1032 memset (sinfo, 0, sizeof (LLVMSigInfo));
1034 ret_type = type_to_llvm_type (ctx, sig->ret);
1035 CHECK_FAILURE (ctx);
1037 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1038 /* LLVM models this by returning an aggregate value */
1039 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1040 LLVMTypeRef members [2];
1042 members [0] = IntPtrType ();
1043 ret_type = LLVMStructType (members, 1, FALSE);
1045 g_assert_not_reached ();
1047 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1048 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1050 ret_type = LLVMVoidType ();
1053 pindexes = g_new0 (int, sig->param_count);
1054 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1056 if (cinfo && cinfo->rgctx_arg) {
1058 sinfo->rgctx_arg_pindex = pindex;
1059 param_types [pindex] = IntPtrType ();
1062 if (cinfo && cinfo->imt_arg) {
1064 sinfo->imt_arg_pindex = pindex;
1065 param_types [pindex] = IntPtrType ();
1069 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1070 vret_arg_pindex = pindex;
1071 if (cinfo->vret_arg_index == 1) {
1072 /* Add the slots consumed by the first argument */
1073 LLVMArgInfo *ainfo = &cinfo->args [0];
1074 switch (ainfo->storage) {
1075 case LLVMArgVtypeInReg:
1076 for (j = 0; j < 2; ++j) {
1077 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1087 sinfo->vret_arg_pindex = vret_arg_pindex;
1090 if (vretaddr && vret_arg_pindex == pindex)
1091 param_types [pindex ++] = IntPtrType ();
1094 sinfo->this_arg_pindex = pindex;
1095 param_types [pindex ++] = IntPtrType ();
1097 if (vretaddr && vret_arg_pindex == pindex)
1098 param_types [pindex ++] = IntPtrType ();
1099 for (i = 0; i < sig->param_count; ++i) {
1100 if (vretaddr && vret_arg_pindex == pindex)
1101 param_types [pindex ++] = IntPtrType ();
1102 pindexes [i] = pindex;
1103 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1104 for (j = 0; j < 2; ++j) {
1105 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1107 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1112 g_assert_not_reached ();
1115 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1116 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1117 CHECK_FAILURE (ctx);
1118 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1121 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1124 if (vretaddr && vret_arg_pindex == pindex)
1125 param_types [pindex ++] = IntPtrType ();
1127 CHECK_FAILURE (ctx);
1129 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1130 g_free (param_types);
1133 sinfo->pindexes = pindexes;
1141 g_free (param_types);
1147 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1149 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1153 * LLVMFunctionType1:
1155 * Create an LLVM function type from the arguments.
1157 static G_GNUC_UNUSED LLVMTypeRef
1158 LLVMFunctionType1(LLVMTypeRef ReturnType,
1159 LLVMTypeRef ParamType1,
1162 LLVMTypeRef param_types [1];
1164 param_types [0] = ParamType1;
1166 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1170 * LLVMFunctionType2:
1172 * Create an LLVM function type from the arguments.
1174 static G_GNUC_UNUSED LLVMTypeRef
1175 LLVMFunctionType2(LLVMTypeRef ReturnType,
1176 LLVMTypeRef ParamType1,
1177 LLVMTypeRef ParamType2,
1180 LLVMTypeRef param_types [2];
1182 param_types [0] = ParamType1;
1183 param_types [1] = ParamType2;
1185 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1189 * LLVMFunctionType3:
1191 * Create an LLVM function type from the arguments.
1193 static G_GNUC_UNUSED LLVMTypeRef
1194 LLVMFunctionType3(LLVMTypeRef ReturnType,
1195 LLVMTypeRef ParamType1,
1196 LLVMTypeRef ParamType2,
1197 LLVMTypeRef ParamType3,
1200 LLVMTypeRef param_types [3];
1202 param_types [0] = ParamType1;
1203 param_types [1] = ParamType2;
1204 param_types [2] = ParamType3;
1206 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1212 * Create an LLVM builder and remember it so it can be freed later.
1214 static LLVMBuilderRef
1215 create_builder (EmitContext *ctx)
1217 LLVMBuilderRef builder = LLVMCreateBuilder ();
1219 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1225 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1227 char *callee_name = mono_aot_get_plt_symbol (type, data);
1228 LLVMValueRef callee;
1233 if (ctx->cfg->compile_aot)
1234 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1235 mono_add_patch_info (ctx->cfg, 0, type, data);
1238 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1240 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1242 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1244 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1251 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1253 MonoMethodHeader *header = cfg->header;
1254 MonoExceptionClause *clause;
1258 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1259 return (bb->region >> 8) - 1;
1262 for (i = 0; i < header->num_clauses; ++i) {
1263 clause = &header->clauses [i];
1265 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1273 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1275 LLVMValueRef md_arg;
1278 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1279 md_arg = LLVMMDString ("mono", 4);
1280 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1286 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1290 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1292 MonoCompile *cfg = ctx->cfg;
1294 LLVMBuilderRef builder = *builder_ref;
1297 clause_index = get_handler_clause (cfg, bb);
1299 if (clause_index != -1) {
1300 MonoMethodHeader *header = cfg->header;
1301 MonoExceptionClause *ec = &header->clauses [clause_index];
1302 MonoBasicBlock *tblock;
1303 LLVMBasicBlockRef ex_bb, noex_bb;
1306 * Have to use an invoke instead of a call, branching to the
1307 * handler bblock of the clause containing this bblock.
1310 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1312 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1315 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1317 ex_bb = get_bb (ctx, tblock);
1319 noex_bb = gen_bb (ctx, "NOEX_BB");
1322 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1324 builder = ctx->builder = create_builder (ctx);
1325 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1327 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1329 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1330 ctx->builder = builder;
1333 *builder_ref = ctx->builder;
1339 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1341 const char *intrins_name;
1342 LLVMValueRef args [16], res;
1343 LLVMTypeRef addr_type;
1345 if (is_faulting && bb->region != -1) {
1347 * We handle loads which can fault by calling a mono specific intrinsic
1348 * using an invoke, so they are handled properly inside try blocks.
1349 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1350 * are marked with IntrReadArgMem.
1354 intrins_name = "llvm.mono.load.i8.p0i8";
1357 intrins_name = "llvm.mono.load.i16.p0i16";
1360 intrins_name = "llvm.mono.load.i32.p0i32";
1363 intrins_name = "llvm.mono.load.i64.p0i64";
1366 g_assert_not_reached ();
1369 addr_type = LLVMTypeOf (addr);
1370 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1371 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1374 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1375 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1376 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1378 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1379 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1380 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1381 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1388 * We emit volatile loads for loads which can fault, because otherwise
1389 * LLVM will generate invalid code when encountering a load from a
1392 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1394 /* Mark it with a custom metadata */
1397 set_metadata_flag (res, "mono.faulting.load");
1405 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1407 const char *intrins_name;
1408 LLVMValueRef args [16];
1410 if (is_faulting && bb->region != -1) {
1413 intrins_name = "llvm.mono.store.i8.p0i8";
1416 intrins_name = "llvm.mono.store.i16.p0i16";
1419 intrins_name = "llvm.mono.store.i32.p0i32";
1422 intrins_name = "llvm.mono.store.i64.p0i64";
1425 g_assert_not_reached ();
1428 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1429 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1430 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1435 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1436 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1437 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1439 LLVMBuildStore (*builder_ref, value, addr);
1444 * emit_cond_system_exception:
1446 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1447 * Might set the ctx exception.
1450 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1452 LLVMBasicBlockRef ex_bb, noex_bb;
1453 LLVMBuilderRef builder;
1454 MonoClass *exc_class;
1455 LLVMValueRef args [2];
1457 ex_bb = gen_bb (ctx, "EX_BB");
1458 noex_bb = gen_bb (ctx, "NOEX_BB");
1460 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1462 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1463 g_assert (exc_class);
1465 /* Emit exception throwing code */
1466 builder = create_builder (ctx);
1467 LLVMPositionBuilderAtEnd (builder, ex_bb);
1469 if (!ctx->lmodule->throw_corlib_exception) {
1470 LLVMValueRef callee;
1472 const char *icall_name;
1474 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1475 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1476 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1477 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1478 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1479 sig = sig_to_llvm_sig (ctx, throw_sig);
1481 if (ctx->cfg->compile_aot) {
1482 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1484 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1487 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1488 * - On x86, LLVM generated code doesn't push the arguments
1489 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1490 * arguments, not a pc offset.
1492 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1495 mono_memory_barrier ();
1496 ctx->lmodule->throw_corlib_exception = callee;
1500 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1502 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1505 * The LLVM mono branch contains changes so a block address can be passed as an
1506 * argument to a call.
1508 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1509 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1511 LLVMBuildUnreachable (builder);
1513 ctx->builder = create_builder (ctx);
1514 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1516 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1523 * emit_reg_to_vtype:
1525 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1528 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1532 size = get_vtype_size (t);
1534 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1535 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1538 for (j = 0; j < 2; ++j) {
1539 LLVMValueRef index [2], addr;
1540 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1541 LLVMTypeRef part_type;
1543 if (ainfo->pair_storage [j] == LLVMArgNone)
1546 part_type = LLVMIntType (part_size * 8);
1547 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1548 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1549 addr = LLVMBuildGEP (builder, address, index, 1, "");
1551 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1552 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1553 addr = LLVMBuildGEP (builder, address, index, 2, "");
1555 switch (ainfo->pair_storage [j]) {
1557 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1562 g_assert_not_reached ();
1565 size -= sizeof (gpointer);
1570 * emit_vtype_to_reg:
1572 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1573 * into REGS, and the number of registers into NREGS.
1576 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1581 size = get_vtype_size (t);
1583 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1584 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1587 for (j = 0; j < 2; ++j) {
1588 LLVMValueRef index [2], addr;
1589 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1591 if (ainfo->pair_storage [j] == LLVMArgNone)
1594 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1595 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1596 addr = LLVMBuildGEP (builder, address, index, 1, "");
1598 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1599 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1600 addr = LLVMBuildGEP (builder, address, index, 2, "");
1602 switch (ainfo->pair_storage [j]) {
1604 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1609 g_assert_not_reached ();
1611 size -= sizeof (gpointer);
1618 build_alloca (EmitContext *ctx, MonoType *t)
1620 MonoClass *k = mono_class_from_mono_type (t);
1623 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1626 align = mono_class_min_align (k);
1628 /* Sometimes align is not a power of 2 */
1629 while (mono_is_power_of_two (align) == -1)
1633 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1634 * get executed every time control reaches them.
1636 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1638 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1639 return ctx->last_alloca;
1643 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1646 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1648 LLVMTypeRef used_type;
1649 LLVMValueRef used, used_elem;
1651 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1652 used = LLVMAddGlobal (module, used_type, "llvm.used");
1653 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1654 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1655 LLVMSetLinkage (used, LLVMAppendingLinkage);
1656 LLVMSetSection (used, "llvm.metadata");
1662 * Emit code to load/convert arguments.
1665 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1668 MonoCompile *cfg = ctx->cfg;
1669 MonoMethodSignature *sig = ctx->sig;
1670 LLVMCallInfo *linfo = ctx->linfo;
1673 ctx->alloca_builder = create_builder (ctx);
1676 * Handle indirect/volatile variables by allocating memory for them
1677 * using 'alloca', and storing their address in a temporary.
1679 for (i = 0; i < cfg->num_varinfo; ++i) {
1680 MonoInst *var = cfg->varinfo [i];
1683 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1684 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1685 CHECK_FAILURE (ctx);
1686 /* Could be already created by an OP_VPHI */
1687 if (!ctx->addresses [var->dreg])
1688 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1689 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1693 for (i = 0; i < sig->param_count; ++i) {
1694 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1695 int reg = cfg->args [i + sig->hasthis]->dreg;
1697 if (ainfo->storage == LLVMArgVtypeInReg) {
1698 LLVMValueRef regs [2];
1701 * Emit code to save the argument from the registers to
1702 * the real argument.
1704 pindex = ctx->pindexes [i];
1705 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1706 if (ainfo->pair_storage [1] != LLVMArgNone)
1707 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1711 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1713 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1715 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1716 /* Treat these as normal values */
1717 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1719 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1720 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1722 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1723 /* Treat these as normal values */
1724 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1727 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1732 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1734 emit_volatile_store (ctx, cfg->args [0]->dreg);
1735 for (i = 0; i < sig->param_count; ++i)
1736 if (!mini_type_is_vtype (cfg, sig->params [i]))
1737 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1739 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1740 LLVMValueRef this_alloc;
1743 * The exception handling code needs the location where the this argument was
1744 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1745 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1746 * location into the LSDA.
1748 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1749 /* This volatile store will keep the alloca alive */
1750 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1752 set_metadata_flag (this_alloc, "mono.this");
1755 if (cfg->rgctx_var) {
1756 LLVMValueRef rgctx_alloc, store;
1759 * We handle the rgctx arg similarly to the this pointer.
1761 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1762 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1763 /* This volatile store will keep the alloca alive */
1764 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1766 set_metadata_flag (rgctx_alloc, "mono.this");
1770 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1771 * it needs to continue normally, or return back to the exception handling system.
1773 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1774 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1775 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1776 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1780 sprintf (name, "finally_ind_bb%d", bb->block_num);
1781 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1782 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1784 ctx->bblocks [bb->block_num].finally_ind = val;
1787 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1788 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1789 * LLVM optimizer passes.
1791 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1792 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1800 /* Have to export this for AOT */
1802 mono_personality (void);
1805 mono_personality (void)
1808 g_assert_not_reached ();
1812 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1814 MonoCompile *cfg = ctx->cfg;
1815 LLVMModuleRef module = ctx->module;
1816 LLVMValueRef *values = ctx->values;
1817 LLVMValueRef *addresses = ctx->addresses;
1818 MonoCallInst *call = (MonoCallInst*)ins;
1819 MonoMethodSignature *sig = call->signature;
1820 LLVMValueRef callee = NULL, lcall;
1822 LLVMCallInfo *cinfo;
1826 LLVMTypeRef llvm_sig;
1828 gboolean virtual, calli;
1829 LLVMBuilderRef builder = *builder_ref;
1832 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1833 LLVM_FAILURE (ctx, "non-default callconv");
1835 cinfo = call->cinfo;
1836 if (call->rgctx_arg_reg)
1837 cinfo->rgctx_arg = TRUE;
1838 if (call->imt_arg_reg)
1839 cinfo->imt_arg = TRUE;
1841 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1843 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1844 CHECK_FAILURE (ctx);
1846 virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE);
1847 calli = (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG);
1849 /* FIXME: Avoid creating duplicate methods */
1851 if (ins->flags & MONO_INST_HAS_METHOD) {
1855 if (cfg->compile_aot) {
1856 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1858 LLVM_FAILURE (ctx, "can't encode patch");
1860 callee = LLVMAddFunction (module, "", llvm_sig);
1863 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1865 LLVMAddGlobalMapping (ee, callee, target);
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 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
1947 len = sizeof (LLVMValueRef) * nargs;
1948 args = alloca (len);
1949 memset (args, 0, len);
1950 l = call->out_ireg_args;
1952 if (call->rgctx_arg_reg) {
1953 g_assert (values [call->rgctx_arg_reg]);
1954 g_assert (sinfo.rgctx_arg_pindex < nargs);
1955 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1957 if (call->imt_arg_reg) {
1958 g_assert (values [call->imt_arg_reg]);
1959 g_assert (sinfo.imt_arg_pindex < nargs);
1960 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1964 if (!addresses [call->inst.dreg])
1965 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1966 g_assert (sinfo.vret_arg_pindex < nargs);
1967 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1970 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1973 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1977 pindex = sinfo.this_arg_pindex;
1979 pindex = sinfo.pindexes [i - 1];
1981 pindex = sinfo.pindexes [i];
1984 regpair = (guint32)(gssize)(l->data);
1985 reg = regpair & 0xffffff;
1986 args [pindex] = values [reg];
1987 if (ainfo->storage == LLVMArgVtypeInReg) {
1989 LLVMValueRef regs [2];
1994 g_assert (addresses [reg]);
1996 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
1997 for (j = 0; j < nregs; ++j)
1998 args [pindex ++] = regs [j];
2001 // FIXME: Get rid of the VMOVE
2002 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2003 g_assert (addresses [reg]);
2004 args [pindex] = addresses [reg];
2006 g_assert (args [pindex]);
2007 if (i == 0 && sig->hasthis)
2008 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2010 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2016 // FIXME: Align call sites
2022 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2024 #ifdef LLVM_MONO_BRANCH
2026 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2028 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2029 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2031 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2032 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2034 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2036 if (call->rgctx_arg_reg)
2037 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2038 if (call->imt_arg_reg)
2039 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2042 /* Add byval attributes if needed */
2043 for (i = 0; i < sig->param_count; ++i) {
2044 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2046 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2047 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2052 * Convert the result
2054 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2055 LLVMValueRef regs [2];
2057 if (!addresses [ins->dreg])
2058 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2060 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2061 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2062 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2064 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2065 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2066 /* If the method returns an unsigned value, need to zext it */
2068 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));
2071 *builder_ref = ctx->builder;
2073 g_free (sinfo.pindexes);
2081 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2083 MonoCompile *cfg = ctx->cfg;
2084 MonoMethodSignature *sig = ctx->sig;
2085 LLVMValueRef method = ctx->lmethod;
2086 LLVMValueRef *values = ctx->values;
2087 LLVMValueRef *addresses = ctx->addresses;
2089 LLVMCallInfo *linfo = ctx->linfo;
2090 LLVMModuleRef module = ctx->module;
2091 BBInfo *bblocks = ctx->bblocks;
2093 LLVMBasicBlockRef cbb;
2094 LLVMBuilderRef builder, starting_builder;
2095 gboolean has_terminator;
2097 LLVMValueRef lhs, rhs;
2100 cbb = get_bb (ctx, bb);
2101 builder = create_builder (ctx);
2102 ctx->builder = builder;
2103 LLVMPositionBuilderAtEnd (builder, cbb);
2105 if (bb == cfg->bb_entry)
2106 emit_entry_bb (ctx, builder);
2107 CHECK_FAILURE (ctx);
2109 if (bb->flags & BB_EXCEPTION_HANDLER) {
2111 LLVMValueRef personality;
2112 LLVMBasicBlockRef target_bb;
2114 static gint32 mapping_inited;
2115 static int ti_generator;
2118 LLVMValueRef type_info;
2121 if (!bblocks [bb->block_num].invoke_target) {
2123 * LLVM asserts if llvm.eh.selector is called from a bblock which
2124 * doesn't have an invoke pointing at it.
2125 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2127 LLVM_FAILURE (ctx, "handler without invokes");
2130 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2132 if (cfg->compile_aot) {
2133 /* Use a dummy personality function */
2134 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2135 g_assert (personality);
2137 personality = LLVMGetNamedFunction (module, "mono_personality");
2138 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2139 LLVMAddGlobalMapping (ee, personality, mono_personality);
2142 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2144 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2147 * Create the type info
2149 sprintf (ti_name, "type_info_%d", ti_generator);
2152 if (cfg->compile_aot) {
2153 /* decode_eh_frame () in aot-runtime.c will decode this */
2154 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2155 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2158 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2160 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2163 * Enabling this causes llc to crash:
2164 * http://llvm.org/bugs/show_bug.cgi?id=6102
2166 //LLVM_FAILURE (ctx, "aot+clauses");
2168 // test_0_invalid_unbox_arrays () fails
2169 LLVM_FAILURE (ctx, "aot+clauses");
2173 * After the cfg mempool is freed, the type info will point to stale memory,
2174 * but this is not a problem, since we decode it once in exception_cb during
2177 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2178 *(gint32*)ti = clause_index;
2180 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2182 LLVMAddGlobalMapping (ee, type_info, ti);
2186 LLVMTypeRef members [2], ret_type;
2187 LLVMValueRef landing_pad;
2189 members [0] = i8ptr;
2190 members [1] = LLVMInt32Type ();
2191 ret_type = LLVMStructType (members, 2, FALSE);
2193 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2194 LLVMAddClause (landing_pad, type_info);
2196 /* Store the exception into the exvar */
2197 if (bb->in_scount == 1) {
2198 g_assert (bb->in_scount == 1);
2199 exvar = bb->in_stack [0];
2201 // FIXME: This is shared with filter clauses ?
2202 g_assert (!values [exvar->dreg]);
2204 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2205 emit_volatile_store (ctx, exvar->dreg);
2209 /* Start a new bblock which CALL_HANDLER can branch to */
2210 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2212 LLVMBuildBr (builder, target_bb);
2214 ctx->builder = builder = create_builder (ctx);
2215 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2217 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2221 has_terminator = FALSE;
2222 starting_builder = builder;
2223 for (ins = bb->code; ins; ins = ins->next) {
2224 const char *spec = LLVM_INS_INFO (ins->opcode);
2226 char dname_buf [128];
2229 if (nins > 5000 && builder == starting_builder) {
2230 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2231 LLVM_FAILURE (ctx, "basic block too long");
2235 /* There could be instructions after a terminator, skip them */
2238 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2239 sprintf (dname_buf, "t%d", ins->dreg);
2243 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2244 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2246 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2247 lhs = emit_volatile_load (ctx, ins->sreg1);
2249 /* It is ok for SETRET to have an uninitialized argument */
2250 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2251 LLVM_FAILURE (ctx, "sreg1");
2252 lhs = values [ins->sreg1];
2258 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2259 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2260 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2261 rhs = emit_volatile_load (ctx, ins->sreg2);
2263 if (!values [ins->sreg2])
2264 LLVM_FAILURE (ctx, "sreg2");
2265 rhs = values [ins->sreg2];
2271 //mono_print_ins (ins);
2272 switch (ins->opcode) {
2275 case OP_LIVERANGE_START:
2276 case OP_LIVERANGE_END:
2279 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2282 #if SIZEOF_VOID_P == 4
2283 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2285 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2289 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2292 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2295 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2296 has_terminator = TRUE;
2302 LLVMBasicBlockRef new_bb;
2303 LLVMBuilderRef new_builder;
2305 // The default branch is already handled
2306 // FIXME: Handle it here
2308 /* Start new bblock */
2309 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2310 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2312 lhs = convert (ctx, lhs, LLVMInt32Type ());
2313 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2314 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2315 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2317 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2320 new_builder = create_builder (ctx);
2321 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2322 LLVMBuildUnreachable (new_builder);
2324 has_terminator = TRUE;
2325 g_assert (!ins->next);
2331 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2332 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2333 LLVMValueRef part1, retval;
2336 size = get_vtype_size (sig->ret);
2338 g_assert (addresses [ins->sreg1]);
2340 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2341 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2343 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2345 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2347 LLVMBuildRet (builder, retval);
2351 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2352 LLVMBuildRetVoid (builder);
2356 if (!lhs || ctx->is_dead [ins->sreg1]) {
2358 * The method did not set its return value, probably because it
2359 * ends with a throw.
2362 LLVMBuildRetVoid (builder);
2364 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2366 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2368 has_terminator = TRUE;
2374 case OP_ICOMPARE_IMM:
2375 case OP_LCOMPARE_IMM:
2376 case OP_COMPARE_IMM: {
2380 if (ins->next->opcode == OP_NOP)
2383 if (ins->next->opcode == OP_BR)
2384 /* The comparison result is not needed */
2387 rel = mono_opcode_to_cond (ins->next->opcode);
2389 if (ins->opcode == OP_ICOMPARE_IMM) {
2390 lhs = convert (ctx, lhs, LLVMInt32Type ());
2391 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2393 if (ins->opcode == OP_LCOMPARE_IMM) {
2394 lhs = convert (ctx, lhs, LLVMInt64Type ());
2395 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2397 if (ins->opcode == OP_LCOMPARE) {
2398 lhs = convert (ctx, lhs, LLVMInt64Type ());
2399 rhs = convert (ctx, rhs, LLVMInt64Type ());
2401 if (ins->opcode == OP_ICOMPARE) {
2402 lhs = convert (ctx, lhs, LLVMInt32Type ());
2403 rhs = convert (ctx, rhs, LLVMInt32Type ());
2407 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2408 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2409 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2410 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2413 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2414 if (ins->opcode == OP_FCOMPARE)
2415 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2416 else if (ins->opcode == OP_COMPARE_IMM)
2417 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2418 else if (ins->opcode == OP_LCOMPARE_IMM) {
2419 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2420 /* The immediate is encoded in two fields */
2421 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2422 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2424 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2427 else if (ins->opcode == OP_COMPARE)
2428 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2430 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2432 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2433 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2435 * If the target bb contains PHI instructions, LLVM requires
2436 * two PHI entries for this bblock, while we only generate one.
2437 * So convert this to an unconditional bblock. (bxc #171).
2439 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2441 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2443 has_terminator = TRUE;
2444 } else if (MONO_IS_SETCC (ins->next)) {
2445 sprintf (dname_buf, "t%d", ins->next->dreg);
2447 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2449 /* Add stores for volatile variables */
2450 emit_volatile_store (ctx, ins->next->dreg);
2451 } else if (MONO_IS_COND_EXC (ins->next)) {
2452 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2453 CHECK_FAILURE (ctx);
2454 builder = ctx->builder;
2456 LLVM_FAILURE (ctx, "next");
2470 rel = mono_opcode_to_cond (ins->opcode);
2472 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2473 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2481 gboolean empty = TRUE;
2483 /* Check that all input bblocks really branch to us */
2484 for (i = 0; i < bb->in_count; ++i) {
2485 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2486 ins->inst_phi_args [i + 1] = -1;
2492 /* LLVM doesn't like phi instructions with zero operands */
2493 ctx->is_dead [ins->dreg] = TRUE;
2497 /* Created earlier, insert it now */
2498 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2500 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2501 int sreg1 = ins->inst_phi_args [i + 1];
2505 * Count the number of times the incoming bblock branches to us,
2506 * since llvm requires a separate entry for each.
2508 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2509 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2512 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2513 if (switch_ins->inst_many_bb [j] == bb)
2520 /* Remember for later */
2521 for (j = 0; j < count; ++j) {
2522 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2525 node->in_bb = bb->in_bb [i];
2527 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);
2537 values [ins->dreg] = lhs;
2540 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2543 values [ins->dreg] = lhs;
2545 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2547 * This is added by the spilling pass in case of the JIT,
2548 * but we have to do it ourselves.
2550 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2584 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2585 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2587 switch (ins->opcode) {
2590 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2594 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2598 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2602 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2606 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2610 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2614 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2617 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2621 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2625 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2629 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2633 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2637 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2641 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2645 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2648 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2651 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2655 g_assert_not_reached ();
2662 case OP_IREM_UN_IMM:
2664 case OP_IDIV_UN_IMM:
2670 case OP_ISHR_UN_IMM:
2679 case OP_LSHR_UN_IMM:
2687 if (spec [MONO_INST_SRC1] == 'l') {
2688 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2690 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2693 #if SIZEOF_VOID_P == 4
2694 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2695 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2698 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2699 lhs = convert (ctx, lhs, IntPtrType ());
2700 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2701 switch (ins->opcode) {
2705 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2709 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2713 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2717 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2719 case OP_IDIV_UN_IMM:
2720 case OP_LDIV_UN_IMM:
2721 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2725 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2727 case OP_IREM_UN_IMM:
2728 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2733 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2737 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2741 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2746 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2751 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2753 case OP_ISHR_UN_IMM:
2754 /* This is used to implement conv.u4, so the lhs could be an i8 */
2755 lhs = convert (ctx, lhs, LLVMInt32Type ());
2756 imm = convert (ctx, imm, LLVMInt32Type ());
2757 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2759 case OP_LSHR_UN_IMM:
2760 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2763 g_assert_not_reached ();
2768 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2771 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2774 lhs = convert (ctx, lhs, LLVMDoubleType ());
2775 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2778 guint32 v = 0xffffffff;
2779 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2783 guint64 v = 0xffffffffffffffffLL;
2784 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2787 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2789 LLVMValueRef v1, v2;
2791 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2792 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2793 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2798 case OP_ICONV_TO_I1:
2799 case OP_ICONV_TO_I2:
2800 case OP_ICONV_TO_I4:
2801 case OP_ICONV_TO_U1:
2802 case OP_ICONV_TO_U2:
2803 case OP_ICONV_TO_U4:
2804 case OP_LCONV_TO_I1:
2805 case OP_LCONV_TO_I2:
2806 case OP_LCONV_TO_U1:
2807 case OP_LCONV_TO_U2:
2808 case OP_LCONV_TO_U4: {
2811 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);
2813 /* Have to do two casts since our vregs have type int */
2814 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2816 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2818 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2821 case OP_ICONV_TO_I8:
2822 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2824 case OP_ICONV_TO_U8:
2825 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2827 case OP_FCONV_TO_I4:
2828 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2830 case OP_FCONV_TO_I1:
2831 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2833 case OP_FCONV_TO_U1:
2834 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2836 case OP_FCONV_TO_I2:
2837 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2839 case OP_FCONV_TO_U2:
2840 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2842 case OP_FCONV_TO_I8:
2843 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2846 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2848 case OP_ICONV_TO_R8:
2849 case OP_LCONV_TO_R8:
2850 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2852 case OP_LCONV_TO_R_UN:
2853 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2855 #if SIZEOF_VOID_P == 4
2858 case OP_LCONV_TO_I4:
2859 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2861 case OP_ICONV_TO_R4:
2862 case OP_LCONV_TO_R4:
2863 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2864 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2866 case OP_FCONV_TO_R4:
2867 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2868 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2871 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2874 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2877 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2879 case OP_LOCALLOC_IMM: {
2882 guint32 size = ins->inst_imm;
2883 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2885 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2887 if (ins->flags & MONO_INST_INIT) {
2888 LLVMValueRef args [5];
2891 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2892 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2893 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2894 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2895 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2898 values [ins->dreg] = v;
2902 LLVMValueRef v, size;
2904 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), "");
2906 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2908 if (ins->flags & MONO_INST_INIT) {
2909 LLVMValueRef args [5];
2912 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2914 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2915 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2916 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2918 values [ins->dreg] = v;
2922 case OP_LOADI1_MEMBASE:
2923 case OP_LOADU1_MEMBASE:
2924 case OP_LOADI2_MEMBASE:
2925 case OP_LOADU2_MEMBASE:
2926 case OP_LOADI4_MEMBASE:
2927 case OP_LOADU4_MEMBASE:
2928 case OP_LOADI8_MEMBASE:
2929 case OP_LOADR4_MEMBASE:
2930 case OP_LOADR8_MEMBASE:
2931 case OP_LOAD_MEMBASE:
2939 LLVMValueRef base, index, addr;
2941 gboolean sext = FALSE, zext = FALSE;
2942 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2944 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2949 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)) {
2950 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2955 if (ins->inst_offset == 0) {
2957 } else if (ins->inst_offset % size != 0) {
2958 /* Unaligned load */
2959 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2960 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2962 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2963 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2967 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2969 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2971 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2973 * These will signal LLVM that these loads do not alias any stores, and
2974 * they can't fail, allowing them to be hoisted out of loops.
2976 set_metadata_flag (values [ins->dreg], "mono.noalias");
2977 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2981 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2983 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2984 else if (ins->opcode == OP_LOADR4_MEMBASE)
2985 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2989 case OP_STOREI1_MEMBASE_REG:
2990 case OP_STOREI2_MEMBASE_REG:
2991 case OP_STOREI4_MEMBASE_REG:
2992 case OP_STOREI8_MEMBASE_REG:
2993 case OP_STORER4_MEMBASE_REG:
2994 case OP_STORER8_MEMBASE_REG:
2995 case OP_STORE_MEMBASE_REG: {
2997 LLVMValueRef index, addr;
2999 gboolean sext = FALSE, zext = FALSE;
3000 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3002 if (!values [ins->inst_destbasereg])
3003 LLVM_FAILURE (ctx, "inst_destbasereg");
3005 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3007 if (ins->inst_offset % size != 0) {
3008 /* Unaligned store */
3009 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3010 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3012 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3013 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3015 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3019 case OP_STOREI1_MEMBASE_IMM:
3020 case OP_STOREI2_MEMBASE_IMM:
3021 case OP_STOREI4_MEMBASE_IMM:
3022 case OP_STOREI8_MEMBASE_IMM:
3023 case OP_STORE_MEMBASE_IMM: {
3025 LLVMValueRef index, addr;
3027 gboolean sext = FALSE, zext = FALSE;
3028 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3030 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3032 if (ins->inst_offset % size != 0) {
3033 /* Unaligned store */
3034 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3035 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3037 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3038 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3040 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3045 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3047 case OP_OUTARG_VTRETADDR:
3054 case OP_VOIDCALL_MEMBASE:
3055 case OP_CALL_MEMBASE:
3056 case OP_LCALL_MEMBASE:
3057 case OP_FCALL_MEMBASE:
3058 case OP_VCALL_MEMBASE:
3059 case OP_VOIDCALL_REG:
3063 case OP_VCALL_REG: {
3064 process_call (ctx, bb, &builder, ins);
3065 CHECK_FAILURE (ctx);
3070 LLVMValueRef indexes [2];
3072 LLVMValueRef got_entry_addr;
3075 * FIXME: Can't allocate from the cfg mempool since that is freed if
3076 * the LLVM compile fails.
3078 ji = g_new0 (MonoJumpInfo, 1);
3079 ji->type = (MonoJumpInfoType)ins->inst_i1;
3080 ji->data.target = ins->inst_p0;
3082 ji = mono_aot_patch_info_dup (ji);
3084 ji->next = cfg->patch_info;
3085 cfg->patch_info = ji;
3087 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3088 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3090 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3091 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3092 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3094 // FIXME: This doesn't work right now, because it must be
3095 // paired with an invariant.end, and even then, its only in effect
3096 // inside its basic block
3099 LLVMValueRef args [3];
3100 LLVMValueRef ptr, val;
3102 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3104 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3106 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3110 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3113 case OP_NOT_REACHED:
3114 LLVMBuildUnreachable (builder);
3115 has_terminator = TRUE;
3116 g_assert (bb->block_num < cfg->max_block_num);
3117 ctx->unreachable [bb->block_num] = TRUE;
3118 /* Might have instructions after this */
3120 MonoInst *next = ins->next;
3122 * FIXME: If later code uses the regs defined by these instructions,
3123 * compilation will fail.
3125 MONO_DELETE_INS (bb, next);
3129 MonoInst *var = ins->inst_p0;
3131 values [ins->dreg] = addresses [var->dreg];
3135 LLVMValueRef args [1];
3137 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3138 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3142 LLVMValueRef args [1];
3144 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3145 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3149 LLVMValueRef args [1];
3152 /* This no longer seems to happen */
3154 * LLVM optimizes sqrt(nan) into undefined in
3155 * lib/Analysis/ConstantFolding.cpp
3156 * Also, sqrt(NegativeInfinity) is optimized into 0.
3158 LLVM_FAILURE (ctx, "sqrt");
3160 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3161 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3165 LLVMValueRef args [1];
3167 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3168 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3182 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3183 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3185 switch (ins->opcode) {
3188 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3192 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3196 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3200 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3203 g_assert_not_reached ();
3206 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3209 case OP_ATOMIC_EXCHANGE_I4: {
3210 LLVMValueRef args [2];
3212 g_assert (ins->inst_offset == 0);
3214 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3217 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3220 case OP_ATOMIC_EXCHANGE_I8: {
3221 LLVMValueRef args [2];
3223 g_assert (ins->inst_offset == 0);
3225 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3226 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3227 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3230 case OP_ATOMIC_ADD_NEW_I4: {
3231 LLVMValueRef args [2];
3233 g_assert (ins->inst_offset == 0);
3235 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3237 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3240 case OP_ATOMIC_ADD_NEW_I8: {
3241 LLVMValueRef args [2];
3243 g_assert (ins->inst_offset == 0);
3245 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3246 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3247 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3250 case OP_ATOMIC_CAS_I4:
3251 case OP_ATOMIC_CAS_I8: {
3252 LLVMValueRef args [3];
3255 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3256 t = LLVMInt32Type ();
3258 t = LLVMInt64Type ();
3261 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3263 args [1] = convert (ctx, values [ins->sreg3], t);
3265 args [2] = convert (ctx, values [ins->sreg2], t);
3266 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3269 case OP_MEMORY_BARRIER: {
3270 mono_llvm_build_fence (builder);
3273 case OP_RELAXED_NOP: {
3274 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3275 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3282 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3284 // 257 == FS segment register
3285 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3287 // 256 == GS segment register
3288 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3292 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3294 LLVM_FAILURE (ctx, "opcode tls-get");
3304 case OP_IADD_OVF_UN:
3306 case OP_ISUB_OVF_UN:
3308 case OP_IMUL_OVF_UN:
3309 #if SIZEOF_VOID_P == 8
3311 case OP_LADD_OVF_UN:
3313 case OP_LSUB_OVF_UN:
3315 case OP_LMUL_OVF_UN:
3318 LLVMValueRef args [2], val, ovf, func;
3320 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3321 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3322 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3324 val = LLVMBuildCall (builder, func, args, 2, "");
3325 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3326 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3327 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3328 CHECK_FAILURE (ctx);
3329 builder = ctx->builder;
3335 * We currently model them using arrays. Promotion to local vregs is
3336 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3337 * so we always have an entry in cfg->varinfo for them.
3338 * FIXME: Is this needed ?
3341 MonoClass *klass = ins->klass;
3342 LLVMValueRef args [5];
3346 LLVM_FAILURE (ctx, "!klass");
3350 if (!addresses [ins->dreg])
3351 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3352 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3353 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3354 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3356 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3357 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3358 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3362 case OP_STOREV_MEMBASE:
3363 case OP_LOADV_MEMBASE:
3365 MonoClass *klass = ins->klass;
3366 LLVMValueRef src = NULL, dst, args [5];
3367 gboolean done = FALSE;
3371 LLVM_FAILURE (ctx, "!klass");
3375 if (mini_is_gsharedvt_klass (cfg, klass)) {
3377 LLVM_FAILURE (ctx, "gsharedvt");
3381 switch (ins->opcode) {
3382 case OP_STOREV_MEMBASE:
3383 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3384 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3385 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3388 if (!addresses [ins->sreg1]) {
3390 g_assert (values [ins->sreg1]);
3391 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));
3392 LLVMBuildStore (builder, values [ins->sreg1], dst);
3395 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3396 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3399 case OP_LOADV_MEMBASE:
3400 if (!addresses [ins->dreg])
3401 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3402 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3403 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3406 if (!addresses [ins->sreg1])
3407 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3408 if (!addresses [ins->dreg])
3409 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3410 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3411 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3414 g_assert_not_reached ();
3416 CHECK_FAILURE (ctx);
3423 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3424 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3426 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3427 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3428 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3431 case OP_LLVM_OUTARG_VT:
3432 if (!addresses [ins->sreg1]) {
3433 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3434 g_assert (values [ins->sreg1]);
3435 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3437 addresses [ins->dreg] = addresses [ins->sreg1];
3443 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3445 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3448 case OP_LOADX_MEMBASE: {
3449 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3452 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3453 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3456 case OP_STOREX_MEMBASE: {
3457 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3460 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3461 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3468 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3472 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3478 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3482 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3486 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3490 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3493 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3496 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3499 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3503 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3514 LLVMValueRef v = NULL;
3516 switch (ins->opcode) {
3521 t = LLVMVectorType (LLVMInt32Type (), 4);
3522 rt = LLVMVectorType (LLVMFloatType (), 4);
3528 t = LLVMVectorType (LLVMInt64Type (), 2);
3529 rt = LLVMVectorType (LLVMDoubleType (), 2);
3532 t = LLVMInt32Type ();
3533 rt = LLVMInt32Type ();
3534 g_assert_not_reached ();
3537 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3538 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3539 switch (ins->opcode) {
3542 v = LLVMBuildAnd (builder, lhs, rhs, "");
3546 v = LLVMBuildOr (builder, lhs, rhs, "");
3550 v = LLVMBuildXor (builder, lhs, rhs, "");
3554 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3557 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3581 case OP_PADDB_SAT_UN:
3582 case OP_PADDW_SAT_UN:
3583 case OP_PSUBB_SAT_UN:
3584 case OP_PSUBW_SAT_UN:
3592 case OP_PMULW_HIGH_UN: {
3593 LLVMValueRef args [2];
3598 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3605 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3609 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3617 case OP_EXTRACTX_U2:
3619 case OP_EXTRACT_U1: {
3621 gboolean zext = FALSE;
3623 t = simd_op_to_llvm_type (ins->opcode);
3625 switch (ins->opcode) {
3633 case OP_EXTRACTX_U2:
3638 t = LLVMInt32Type ();
3639 g_assert_not_reached ();
3642 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3643 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3645 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3654 case OP_EXPAND_R8: {
3655 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3656 LLVMValueRef mask [16], v;
3658 for (i = 0; i < 16; ++i)
3659 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3661 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3663 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3664 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3669 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3672 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3675 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3678 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3681 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3684 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3695 case OP_EXTRACT_MASK:
3702 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3704 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3708 case OP_ICONV_TO_R8_RAW:
3709 /* Same as OP_ICONV_TO_R8 */
3710 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3715 LLVMValueRef args [3];
3719 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3721 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3726 /* This is only used for implementing shifts by non-immediate */
3727 values [ins->dreg] = lhs;
3738 LLVMValueRef args [3];
3741 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3743 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3754 case OP_PSHLQ_REG: {
3755 LLVMValueRef args [3];
3758 args [1] = values [ins->sreg2];
3760 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3767 case OP_PSHUFLEW_LOW:
3768 case OP_PSHUFLEW_HIGH: {
3770 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3771 int i, mask_size = 0;
3772 int imask = ins->inst_c0;
3774 /* Convert the x86 shuffle mask to LLVM's */
3775 switch (ins->opcode) {
3778 mask [0] = ((imask >> 0) & 3);
3779 mask [1] = ((imask >> 2) & 3);
3780 mask [2] = ((imask >> 4) & 3) + 4;
3781 mask [3] = ((imask >> 6) & 3) + 4;
3782 v1 = values [ins->sreg1];
3783 v2 = values [ins->sreg2];
3787 mask [0] = ((imask >> 0) & 1);
3788 mask [1] = ((imask >> 1) & 1) + 2;
3789 v1 = values [ins->sreg1];
3790 v2 = values [ins->sreg2];
3792 case OP_PSHUFLEW_LOW:
3794 mask [0] = ((imask >> 0) & 3);
3795 mask [1] = ((imask >> 2) & 3);
3796 mask [2] = ((imask >> 4) & 3);
3797 mask [3] = ((imask >> 6) & 3);
3802 v1 = values [ins->sreg1];
3803 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3805 case OP_PSHUFLEW_HIGH:
3811 mask [4] = 4 + ((imask >> 0) & 3);
3812 mask [5] = 4 + ((imask >> 2) & 3);
3813 mask [6] = 4 + ((imask >> 4) & 3);
3814 mask [7] = 4 + ((imask >> 6) & 3);
3815 v1 = values [ins->sreg1];
3816 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3820 mask [0] = ((imask >> 0) & 3);
3821 mask [1] = ((imask >> 2) & 3);
3822 mask [2] = ((imask >> 4) & 3);
3823 mask [3] = ((imask >> 6) & 3);
3824 v1 = values [ins->sreg1];
3825 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3828 g_assert_not_reached ();
3830 for (i = 0; i < mask_size; ++i)
3831 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3833 values [ins->dreg] =
3834 LLVMBuildShuffleVector (builder, v1, v2,
3835 LLVMConstVector (mask_values, mask_size), dname);
3839 case OP_UNPACK_LOWB:
3840 case OP_UNPACK_LOWW:
3841 case OP_UNPACK_LOWD:
3842 case OP_UNPACK_LOWQ:
3843 case OP_UNPACK_LOWPS:
3844 case OP_UNPACK_LOWPD:
3845 case OP_UNPACK_HIGHB:
3846 case OP_UNPACK_HIGHW:
3847 case OP_UNPACK_HIGHD:
3848 case OP_UNPACK_HIGHQ:
3849 case OP_UNPACK_HIGHPS:
3850 case OP_UNPACK_HIGHPD: {
3852 LLVMValueRef mask_values [16];
3853 int i, mask_size = 0;
3854 gboolean low = FALSE;
3856 switch (ins->opcode) {
3857 case OP_UNPACK_LOWB:
3861 case OP_UNPACK_LOWW:
3865 case OP_UNPACK_LOWD:
3866 case OP_UNPACK_LOWPS:
3870 case OP_UNPACK_LOWQ:
3871 case OP_UNPACK_LOWPD:
3875 case OP_UNPACK_HIGHB:
3878 case OP_UNPACK_HIGHW:
3881 case OP_UNPACK_HIGHD:
3882 case OP_UNPACK_HIGHPS:
3885 case OP_UNPACK_HIGHQ:
3886 case OP_UNPACK_HIGHPD:
3890 g_assert_not_reached ();
3894 for (i = 0; i < (mask_size / 2); ++i) {
3896 mask [(i * 2) + 1] = mask_size + i;
3899 for (i = 0; i < (mask_size / 2); ++i) {
3900 mask [(i * 2)] = (mask_size / 2) + i;
3901 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3905 for (i = 0; i < mask_size; ++i)
3906 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3908 values [ins->dreg] =
3909 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3910 LLVMConstVector (mask_values, mask_size), dname);
3915 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3916 LLVMValueRef v, val;
3918 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3919 val = LLVMConstNull (t);
3920 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3921 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3923 values [ins->dreg] = val;
3927 case OP_DUPPS_HIGH: {
3928 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3929 LLVMValueRef v1, v2, val;
3932 if (ins->opcode == OP_DUPPS_LOW) {
3933 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3934 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3936 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3937 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3939 val = LLVMConstNull (t);
3940 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3941 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3942 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3943 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3945 values [ins->dreg] = val;
3955 * EXCEPTION HANDLING
3957 case OP_IMPLICIT_EXCEPTION:
3958 /* This marks a place where an implicit exception can happen */
3959 if (bb->region != -1)
3960 LLVM_FAILURE (ctx, "implicit-exception");
3964 MonoMethodSignature *throw_sig;
3965 LLVMValueRef callee, arg;
3966 gboolean rethrow = (ins->opcode == OP_RETHROW);
3967 const char *icall_name;
3969 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3970 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3973 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3974 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3975 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3976 if (cfg->compile_aot) {
3977 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3979 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3983 * LLVM doesn't push the exception argument, so we need a different
3986 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3988 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3992 mono_memory_barrier ();
3994 ctx->lmodule->rethrow = callee;
3996 ctx->lmodule->throw = callee;
3998 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3999 emit_call (ctx, bb, &builder, callee, &arg, 1);
4002 case OP_CALL_HANDLER: {
4004 * We don't 'call' handlers, but instead simply branch to them.
4005 * The code generated by ENDFINALLY will branch back to us.
4007 LLVMBasicBlockRef noex_bb;
4009 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4011 bb_list = info->call_handler_return_bbs;
4014 * Set the indicator variable for the finally clause.
4016 lhs = info->finally_ind;
4018 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4020 /* Branch to the finally clause */
4021 LLVMBuildBr (builder, info->call_handler_target_bb);
4023 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4024 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4026 builder = ctx->builder = create_builder (ctx);
4027 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4029 bblocks [bb->block_num].end_bblock = noex_bb;
4032 case OP_START_HANDLER: {
4035 case OP_ENDFINALLY: {
4036 LLVMBasicBlockRef resume_bb;
4037 MonoBasicBlock *handler_bb;
4038 LLVMValueRef val, switch_ins, callee;
4042 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4043 g_assert (handler_bb);
4044 info = &bblocks [handler_bb->block_num];
4045 lhs = info->finally_ind;
4048 bb_list = info->call_handler_return_bbs;
4050 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4052 /* Load the finally variable */
4053 val = LLVMBuildLoad (builder, lhs, "");
4055 /* Reset the variable */
4056 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4058 /* Branch to either resume_bb, or to the bblocks in bb_list */
4059 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4061 * The other targets are added at the end to handle OP_CALL_HANDLER
4062 * opcodes processed later.
4064 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4066 builder = ctx->builder = create_builder (ctx);
4067 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4069 if (ctx->cfg->compile_aot) {
4070 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4072 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4074 LLVMBuildCall (builder, callee, NULL, 0, "");
4076 LLVMBuildUnreachable (builder);
4077 has_terminator = TRUE;
4083 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4084 LLVM_FAILURE (ctx, reason);
4089 /* Convert the value to the type required by phi nodes */
4090 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4091 if (!values [ins->dreg])
4093 values [ins->dreg] = addresses [ins->dreg];
4095 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4098 /* Add stores for volatile variables */
4099 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4100 emit_volatile_store (ctx, ins->dreg);
4103 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4104 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4106 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4107 LLVMBuildRetVoid (builder);
4109 if (bb == cfg->bb_entry)
4110 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4119 * mono_llvm_check_method_supported:
4121 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4122 * compiling a method twice.
4125 mono_llvm_check_method_supported (MonoCompile *cfg)
4127 MonoMethodHeader *header = cfg->header;
4128 MonoExceptionClause *clause;
4131 if (cfg->method->save_lmf) {
4132 cfg->exception_message = g_strdup ("lmf");
4133 cfg->disable_llvm = TRUE;
4137 for (i = 0; i < header->num_clauses; ++i) {
4138 clause = &header->clauses [i];
4140 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4142 * FIXME: Some tests still fail with nested clauses.
4144 cfg->exception_message = g_strdup ("nested clauses");
4145 cfg->disable_llvm = TRUE;
4151 if (cfg->method->dynamic) {
4152 cfg->exception_message = g_strdup ("dynamic.");
4153 cfg->disable_llvm = TRUE;
4158 * mono_llvm_emit_method:
4160 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4163 mono_llvm_emit_method (MonoCompile *cfg)
4166 MonoMethodSignature *sig;
4168 LLVMTypeRef method_type;
4169 LLVMValueRef method = NULL;
4171 LLVMValueRef *values;
4172 int i, max_block_num, bb_index;
4173 gboolean last = FALSE;
4174 GPtrArray *phi_values;
4175 LLVMCallInfo *linfo;
4177 LLVMModuleRef module;
4179 GPtrArray *bblock_list;
4180 MonoMethodHeader *header;
4181 MonoExceptionClause *clause;
4185 /* The code below might acquire the loader lock, so use it for global locking */
4186 mono_loader_lock ();
4188 /* Used to communicate with the callbacks */
4189 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4191 ctx = g_new0 (EmitContext, 1);
4193 ctx->mempool = cfg->mempool;
4196 * This maps vregs to the LLVM instruction defining them
4198 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4200 * This maps vregs for volatile variables to the LLVM instruction defining their
4203 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4204 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4205 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4206 phi_values = g_ptr_array_new ();
4208 * This signals whenever the vreg was defined by a phi node with no input vars
4209 * (i.e. all its input bblocks end with NOT_REACHABLE).
4211 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4212 /* Whenever the bblock is unreachable */
4213 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4215 bblock_list = g_ptr_array_new ();
4217 ctx->values = values;
4218 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4220 if (cfg->compile_aot) {
4221 ctx->lmodule = &aot_module;
4222 method_name = mono_aot_get_method_name (cfg);
4223 cfg->llvm_method_name = g_strdup (method_name);
4226 ctx->lmodule = &jit_module;
4227 method_name = mono_method_full_name (cfg->method, TRUE);
4230 module = ctx->module = ctx->lmodule->module;
4233 LLVM_FAILURE (ctx, "gsharedvt");
4237 static int count = 0;
4240 if (getenv ("LLVM_COUNT")) {
4241 if (count == atoi (getenv ("LLVM_COUNT"))) {
4242 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4246 if (count > atoi (getenv ("LLVM_COUNT")))
4247 LLVM_FAILURE (ctx, "");
4252 sig = mono_method_signature (cfg->method);
4255 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4257 CHECK_FAILURE (ctx);
4260 linfo->rgctx_arg = TRUE;
4261 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4262 CHECK_FAILURE (ctx);
4265 * This maps parameter indexes in the original signature to the indexes in
4266 * the LLVM signature.
4268 ctx->pindexes = sinfo.pindexes;
4270 method = LLVMAddFunction (module, method_name, method_type);
4271 ctx->lmethod = method;
4273 #ifdef LLVM_MONO_BRANCH
4274 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4276 LLVMSetLinkage (method, LLVMPrivateLinkage);
4278 LLVMAddFunctionAttr (method, LLVMUWTable);
4280 if (cfg->compile_aot) {
4281 LLVMSetLinkage (method, LLVMInternalLinkage);
4282 LLVMSetVisibility (method, LLVMHiddenVisibility);
4284 LLVMSetLinkage (method, LLVMPrivateLinkage);
4287 if (cfg->method->save_lmf)
4288 LLVM_FAILURE (ctx, "lmf");
4290 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4291 LLVM_FAILURE (ctx, "pinvoke signature");
4293 header = cfg->header;
4294 for (i = 0; i < header->num_clauses; ++i) {
4295 clause = &header->clauses [i];
4296 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4297 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4300 if (linfo->rgctx_arg) {
4301 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4303 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4304 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4305 * CC_X86_64_Mono in X86CallingConv.td.
4307 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4308 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4310 if (cfg->vret_addr) {
4311 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4312 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4315 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4316 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4319 names = g_new (char *, sig->param_count);
4320 mono_method_get_param_names (cfg->method, (const char **) names);
4322 for (i = 0; i < sig->param_count; ++i) {
4325 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4326 if (names [i] && names [i][0] != '\0')
4327 name = g_strdup_printf ("arg_%s", names [i]);
4329 name = g_strdup_printf ("arg_%d", i);
4330 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4332 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4333 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4337 if (cfg->compile_aot) {
4338 LLVMValueRef md_args [16];
4339 LLVMValueRef md_node;
4342 method_index = mono_aot_get_method_index (cfg->orig_method);
4343 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4344 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4345 md_node = LLVMMDNode (md_args, 2);
4346 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4347 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4351 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4352 max_block_num = MAX (max_block_num, bb->block_num);
4353 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4355 /* Add branches between non-consecutive bblocks */
4356 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4357 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4358 bb->next_bb != bb->last_ins->inst_false_bb) {
4360 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4361 inst->opcode = OP_BR;
4362 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4363 mono_bblock_add_inst (bb, inst);
4368 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4369 * was later optimized away, so clear these flags, and add them back for the still
4370 * present OP_LDADDR instructions.
4372 for (i = 0; i < cfg->next_vreg; ++i) {
4375 ins = get_vreg_to_inst (cfg, i);
4376 if (ins && ins != cfg->rgctx_var)
4377 ins->flags &= ~MONO_INST_INDIRECT;
4381 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4383 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4385 LLVMBuilderRef builder;
4387 char dname_buf[128];
4389 builder = create_builder (ctx);
4391 for (ins = bb->code; ins; ins = ins->next) {
4392 switch (ins->opcode) {
4397 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4399 CHECK_FAILURE (ctx);
4401 if (ins->opcode == OP_VPHI) {
4402 /* Treat valuetype PHI nodes as operating on the address itself */
4403 g_assert (ins->klass);
4404 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4408 * Have to precreate these, as they can be referenced by
4409 * earlier instructions.
4411 sprintf (dname_buf, "t%d", ins->dreg);
4413 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4415 if (ins->opcode == OP_VPHI)
4416 ctx->addresses [ins->dreg] = values [ins->dreg];
4418 g_ptr_array_add (phi_values, values [ins->dreg]);
4421 * Set the expected type of the incoming arguments since these have
4422 * to have the same type.
4424 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4425 int sreg1 = ins->inst_phi_args [i + 1];
4428 ctx->vreg_types [sreg1] = phi_type;
4433 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4442 * Create an ordering for bblocks, use the depth first order first, then
4443 * put the exception handling bblocks last.
4445 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4446 bb = cfg->bblocks [bb_index];
4447 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4448 g_ptr_array_add (bblock_list, bb);
4449 bblocks [bb->block_num].added = TRUE;
4453 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4454 if (!bblocks [bb->block_num].added)
4455 g_ptr_array_add (bblock_list, bb);
4459 * Second pass: generate code.
4461 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4462 bb = g_ptr_array_index (bblock_list, bb_index);
4464 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4467 process_bb (ctx, bb);
4468 CHECK_FAILURE (ctx);
4471 /* Add incoming phi values */
4472 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4473 GSList *l, *ins_list;
4475 ins_list = bblocks [bb->block_num].phi_nodes;
4477 for (l = ins_list; l; l = l->next) {
4478 PhiNode *node = l->data;
4479 MonoInst *phi = node->phi;
4480 int sreg1 = node->sreg;
4481 LLVMBasicBlockRef in_bb;
4486 in_bb = get_end_bb (ctx, node->in_bb);
4488 if (ctx->unreachable [node->in_bb->block_num])
4491 if (!values [sreg1])
4492 /* Can happen with values in EH clauses */
4493 LLVM_FAILURE (ctx, "incoming phi sreg1");
4495 if (phi->opcode == OP_VPHI) {
4496 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4497 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4499 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4500 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4505 /* Create the SWITCH statements for ENDFINALLY instructions */
4506 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4507 BBInfo *info = &bblocks [bb->block_num];
4509 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4510 LLVMValueRef switch_ins = l->data;
4511 GSList *bb_list = info->call_handler_return_bbs;
4513 for (i = 0; i < g_slist_length (bb_list); ++i)
4514 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4518 if (cfg->verbose_level > 1)
4519 mono_llvm_dump_value (method);
4521 mark_as_used (module, method);
4523 if (cfg->compile_aot) {
4524 /* Don't generate native code, keep the LLVM IR */
4525 if (cfg->compile_aot && cfg->verbose_level)
4526 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4528 //LLVMVerifyFunction(method, 0);
4530 mono_llvm_optimize_method (method);
4532 if (cfg->verbose_level > 1)
4533 mono_llvm_dump_value (method);
4535 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4537 /* Set by emit_cb */
4538 g_assert (cfg->code_len);
4540 /* FIXME: Free the LLVM IL for the function */
4548 /* Need to add unused phi nodes as they can be referenced by other values */
4549 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4550 LLVMBuilderRef builder;
4552 builder = create_builder (ctx);
4553 LLVMPositionBuilderAtEnd (builder, phi_bb);
4555 for (i = 0; i < phi_values->len; ++i) {
4556 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4557 if (LLVMGetInstructionParent (v) == NULL)
4558 LLVMInsertIntoBuilder (builder, v);
4561 LLVMDeleteFunction (method);
4566 g_free (ctx->addresses);
4567 g_free (ctx->vreg_types);
4568 g_free (ctx->vreg_cli_types);
4569 g_free (ctx->pindexes);
4570 g_free (ctx->is_dead);
4571 g_free (ctx->unreachable);
4572 g_ptr_array_free (phi_values, TRUE);
4573 g_free (ctx->bblocks);
4574 g_hash_table_destroy (ctx->region_to_handler);
4575 g_free (method_name);
4576 g_ptr_array_free (bblock_list, TRUE);
4578 for (l = ctx->builders; l; l = l->next) {
4579 LLVMBuilderRef builder = l->data;
4580 LLVMDisposeBuilder (builder);
4585 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4587 mono_loader_unlock ();
4591 * mono_llvm_emit_call:
4593 * Same as mono_arch_emit_call () for LLVM.
4596 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4599 MonoMethodSignature *sig;
4600 int i, n, stack_size;
4605 sig = call->signature;
4606 n = sig->param_count + sig->hasthis;
4608 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4610 if (cfg->disable_llvm)
4613 if (sig->call_convention == MONO_CALL_VARARG) {
4614 cfg->exception_message = g_strdup ("varargs");
4615 cfg->disable_llvm = TRUE;
4618 for (i = 0; i < n; ++i) {
4621 ainfo = call->cinfo->args + i;
4623 in = call->args [i];
4625 /* Simply remember the arguments */
4626 switch (ainfo->storage) {
4628 case LLVMArgInFPReg: {
4629 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4631 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4632 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4633 ins->dreg = mono_alloc_freg (cfg);
4635 MONO_INST_NEW (cfg, ins, OP_MOVE);
4636 ins->dreg = mono_alloc_ireg (cfg);
4638 ins->sreg1 = in->dreg;
4641 case LLVMArgVtypeByVal:
4642 case LLVMArgVtypeInReg:
4643 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4644 ins->dreg = mono_alloc_ireg (cfg);
4645 ins->sreg1 = in->dreg;
4646 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4649 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4650 cfg->exception_message = g_strdup ("ainfo->storage");
4651 cfg->disable_llvm = TRUE;
4655 if (!cfg->disable_llvm) {
4656 MONO_ADD_INS (cfg->cbb, ins);
4657 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4662 static unsigned char*
4663 alloc_cb (LLVMValueRef function, int size)
4667 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4671 return mono_domain_code_reserve (cfg->domain, size);
4673 return mono_domain_code_reserve (mono_domain_get (), size);
4678 emitted_cb (LLVMValueRef function, void *start, void *end)
4682 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4684 cfg->code_len = (guint8*)end - (guint8*)start;
4688 exception_cb (void *data)
4691 MonoJitExceptionInfo *ei;
4692 guint32 ei_len, i, j, nested_len, nindex;
4693 gpointer *type_info;
4694 int this_reg, this_offset;
4696 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4700 * data points to a DWARF FDE structure, convert it to our unwind format and
4702 * An alternative would be to save it directly, and modify our unwinder to work
4705 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);
4707 /* Count nested clauses */
4709 for (i = 0; i < ei_len; ++i) {
4710 for (j = 0; j < ei_len; ++j) {
4711 gint32 cindex1 = *(gint32*)type_info [i];
4712 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4713 gint32 cindex2 = *(gint32*)type_info [j];
4714 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4716 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4722 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4723 cfg->llvm_ex_info_len = ei_len + nested_len;
4724 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4725 /* Fill the rest of the information from the type info */
4726 for (i = 0; i < ei_len; ++i) {
4727 gint32 clause_index = *(gint32*)type_info [i];
4728 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4730 cfg->llvm_ex_info [i].flags = clause->flags;
4731 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4735 * For nested clauses, the LLVM produced exception info associates the try interval with
4736 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4738 /* FIXME: These should be order with the normal clauses */
4740 for (i = 0; i < ei_len; ++i) {
4741 for (j = 0; j < ei_len; ++j) {
4742 gint32 cindex1 = *(gint32*)type_info [i];
4743 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4744 gint32 cindex2 = *(gint32*)type_info [j];
4745 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4747 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4749 * The try interval comes from the nested clause, everything else from the
4752 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4753 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4754 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4759 g_assert (nindex == ei_len + nested_len);
4760 cfg->llvm_this_reg = this_reg;
4761 cfg->llvm_this_offset = this_offset;
4763 /* type_info [i] is cfg mempool allocated, no need to free it */
4770 dlsym_cb (const char *name, void **symbol)
4776 if (!strcmp (name, "__bzero")) {
4777 *symbol = (void*)bzero;
4779 current = mono_dl_open (NULL, 0, NULL);
4782 err = mono_dl_symbol (current, name, symbol);
4784 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4785 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4791 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4793 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4797 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4799 LLVMTypeRef param_types [4];
4801 param_types [0] = param_type1;
4802 param_types [1] = param_type2;
4804 AddFunc (module, name, ret_type, param_types, 2);
4808 add_intrinsics (LLVMModuleRef module)
4810 /* Emit declarations of instrinsics */
4812 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4813 * type doesn't seem to do any locking.
4816 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4818 memset_param_count = 5;
4819 memset_func_name = "llvm.memset.p0i8.i32";
4821 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4825 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4827 memcpy_param_count = 5;
4828 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4830 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4834 LLVMTypeRef params [] = { LLVMDoubleType () };
4836 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4837 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4838 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4840 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4841 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4845 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4846 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4848 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4849 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4850 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4851 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4852 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4853 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4857 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4858 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4860 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4861 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4862 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4863 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4864 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4865 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4869 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4870 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4871 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4873 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4875 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4880 LLVMTypeRef arg_types [2];
4881 LLVMTypeRef ret_type;
4883 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4884 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4885 ret_type = LLVMInt32Type ();
4887 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4889 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4892 /* SSE intrinsics */
4894 LLVMTypeRef ret_type, arg_types [16];
4897 ret_type = type_to_simd_type (MONO_TYPE_I4);
4898 arg_types [0] = ret_type;
4899 arg_types [1] = ret_type;
4900 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4901 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4903 ret_type = type_to_simd_type (MONO_TYPE_I2);
4904 arg_types [0] = ret_type;
4905 arg_types [1] = ret_type;
4906 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4907 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4908 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4909 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4910 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4911 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4912 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4913 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4914 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4915 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4917 ret_type = type_to_simd_type (MONO_TYPE_I1);
4918 arg_types [0] = ret_type;
4919 arg_types [1] = ret_type;
4920 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4921 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4922 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4923 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4924 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4925 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4926 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4928 ret_type = type_to_simd_type (MONO_TYPE_R8);
4929 arg_types [0] = ret_type;
4930 arg_types [1] = ret_type;
4931 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4932 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4933 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4934 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4935 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4937 ret_type = type_to_simd_type (MONO_TYPE_R4);
4938 arg_types [0] = ret_type;
4939 arg_types [1] = ret_type;
4940 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4941 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4942 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4943 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4944 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4947 ret_type = type_to_simd_type (MONO_TYPE_I1);
4948 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4949 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4950 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4951 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4952 ret_type = type_to_simd_type (MONO_TYPE_I2);
4953 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4954 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4955 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4956 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4959 ret_type = type_to_simd_type (MONO_TYPE_R8);
4960 arg_types [0] = ret_type;
4961 arg_types [1] = ret_type;
4962 arg_types [2] = LLVMInt8Type ();
4963 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4964 ret_type = type_to_simd_type (MONO_TYPE_R4);
4965 arg_types [0] = ret_type;
4966 arg_types [1] = ret_type;
4967 arg_types [2] = LLVMInt8Type ();
4968 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4970 /* Conversion ops */
4971 ret_type = type_to_simd_type (MONO_TYPE_R8);
4972 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4973 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4974 ret_type = type_to_simd_type (MONO_TYPE_R4);
4975 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4976 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4977 ret_type = type_to_simd_type (MONO_TYPE_I4);
4978 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4979 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4980 ret_type = type_to_simd_type (MONO_TYPE_I4);
4981 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4982 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4983 ret_type = type_to_simd_type (MONO_TYPE_R4);
4984 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4985 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4986 ret_type = type_to_simd_type (MONO_TYPE_R8);
4987 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4988 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4990 ret_type = type_to_simd_type (MONO_TYPE_I4);
4991 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4992 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4993 ret_type = type_to_simd_type (MONO_TYPE_I4);
4994 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4995 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4998 ret_type = type_to_simd_type (MONO_TYPE_R8);
4999 arg_types [0] = ret_type;
5000 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5001 ret_type = type_to_simd_type (MONO_TYPE_R4);
5002 arg_types [0] = ret_type;
5003 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5004 ret_type = type_to_simd_type (MONO_TYPE_R4);
5005 arg_types [0] = ret_type;
5006 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5007 ret_type = type_to_simd_type (MONO_TYPE_R4);
5008 arg_types [0] = ret_type;
5009 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5012 ret_type = type_to_simd_type (MONO_TYPE_I2);
5013 arg_types [0] = ret_type;
5014 arg_types [1] = LLVMInt32Type ();
5015 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5016 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5017 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5018 ret_type = type_to_simd_type (MONO_TYPE_I4);
5019 arg_types [0] = ret_type;
5020 arg_types [1] = LLVMInt32Type ();
5021 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5022 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5023 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5024 ret_type = type_to_simd_type (MONO_TYPE_I8);
5025 arg_types [0] = ret_type;
5026 arg_types [1] = LLVMInt32Type ();
5027 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5028 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5031 ret_type = LLVMInt32Type ();
5032 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5033 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5036 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5038 /* Load/Store intrinsics */
5040 LLVMTypeRef arg_types [5];
5044 for (i = 1; i <= 8; i *= 2) {
5045 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5046 arg_types [1] = LLVMInt32Type ();
5047 arg_types [2] = LLVMInt1Type ();
5048 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5049 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5051 arg_types [0] = LLVMIntType (i * 8);
5052 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5053 arg_types [2] = LLVMInt32Type ();
5054 arg_types [3] = LLVMInt1Type ();
5055 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5056 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5062 mono_llvm_init (void)
5064 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5068 init_jit_module (void)
5070 MonoJitICallInfo *info;
5072 if (jit_module_inited)
5075 mono_loader_lock ();
5077 if (jit_module_inited) {
5078 mono_loader_unlock ();
5082 jit_module.module = LLVMModuleCreateWithName ("mono");
5084 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5086 add_intrinsics (jit_module.module);
5088 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5090 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5092 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5094 jit_module_inited = TRUE;
5096 mono_loader_unlock ();
5100 mono_llvm_cleanup (void)
5103 mono_llvm_dispose_ee (ee);
5105 if (jit_module.llvm_types)
5106 g_hash_table_destroy (jit_module.llvm_types);
5108 if (aot_module.module)
5109 LLVMDisposeModule (aot_module.module);
5111 LLVMContextDispose (LLVMGetGlobalContext ());
5115 mono_llvm_create_aot_module (const char *got_symbol)
5117 /* Delete previous module */
5118 if (aot_module.plt_entries)
5119 g_hash_table_destroy (aot_module.plt_entries);
5120 if (aot_module.module)
5121 LLVMDisposeModule (aot_module.module);
5123 memset (&aot_module, 0, sizeof (aot_module));
5125 aot_module.module = LLVMModuleCreateWithName ("aot");
5126 aot_module.got_symbol = got_symbol;
5128 add_intrinsics (aot_module.module);
5132 * We couldn't compute the type of the LLVM global representing the got because
5133 * its size is only known after all the methods have been emitted. So create
5134 * a dummy variable, and replace all uses it with the real got variable when
5135 * its size is known in mono_llvm_emit_aot_module ().
5138 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5140 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5141 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5144 /* Add a dummy personality function */
5146 LLVMBasicBlockRef lbb;
5147 LLVMBuilderRef lbuilder;
5148 LLVMValueRef personality;
5150 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5151 LLVMSetLinkage (personality, LLVMInternalLinkage);
5152 lbb = LLVMAppendBasicBlock (personality, "BB0");
5153 lbuilder = LLVMCreateBuilder ();
5154 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5155 LLVMBuildRetVoid (lbuilder);
5158 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5159 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5163 * Emit the aot module into the LLVM bitcode file FILENAME.
5166 mono_llvm_emit_aot_module (const char *filename, int got_size)
5168 LLVMTypeRef got_type;
5169 LLVMValueRef real_got;
5172 * Create the real got variable and replace all uses of the dummy variable with
5175 got_type = LLVMArrayType (IntPtrType (), got_size);
5176 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5177 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5178 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5180 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5182 mark_as_used (aot_module.module, real_got);
5184 /* Delete the dummy got so it doesn't become a global */
5185 LLVMDeleteGlobal (aot_module.got_var);
5191 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5192 g_assert_not_reached ();
5197 LLVMWriteBitcodeToFile (aot_module.module, filename);
5202 - Emit LLVM IR from the mono IR using the LLVM C API.
5203 - The original arch specific code remains, so we can fall back to it if we run
5204 into something we can't handle.
5208 A partial list of issues:
5209 - Handling of opcodes which can throw exceptions.
5211 In the mono JIT, these are implemented using code like this:
5218 push throw_pos - method
5219 call <exception trampoline>
5221 The problematic part is push throw_pos - method, which cannot be represented
5222 in the LLVM IR, since it does not support label values.
5223 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5224 be implemented in JIT mode ?
5225 -> a possible but slower implementation would use the normal exception
5226 throwing code but it would need to control the placement of the throw code
5227 (it needs to be exactly after the compare+branch).
5228 -> perhaps add a PC offset intrinsics ?
5230 - efficient implementation of .ovf opcodes.
5232 These are currently implemented as:
5233 <ins which sets the condition codes>
5236 Some overflow opcodes are now supported by LLVM SVN.
5238 - exception handling, unwinding.
5239 - SSA is disabled for methods with exception handlers
5240 - How to obtain unwind info for LLVM compiled methods ?
5241 -> this is now solved by converting the unwind info generated by LLVM
5243 - LLVM uses the c++ exception handling framework, while we use our home grown
5244 code, and couldn't use the c++ one:
5245 - its not supported under VC++, other exotic platforms.
5246 - it might be impossible to support filter clauses with it.
5250 The trampolines need a predictable call sequence, since they need to disasm
5251 the calling code to obtain register numbers / offsets.
5253 LLVM currently generates this code in non-JIT mode:
5254 mov -0x98(%rax),%eax
5256 Here, the vtable pointer is lost.
5257 -> solution: use one vtable trampoline per class.
5259 - passing/receiving the IMT pointer/RGCTX.
5260 -> solution: pass them as normal arguments ?
5264 LLVM does not allow the specification of argument registers etc. This means
5265 that all calls are made according to the platform ABI.
5267 - passing/receiving vtypes.
5269 Vtypes passed/received in registers are handled by the front end by using
5270 a signature with scalar arguments, and loading the parts of the vtype into those
5273 Vtypes passed on the stack are handled using the 'byval' attribute.
5277 Supported though alloca, we need to emit the load/store code.
5281 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5282 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5283 This is made easier because the IR is already in SSA form.
5284 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5285 types are frequently used incorrectly.
5290 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5291 append the AOT data structures to that file. For methods which cannot be
5292 handled by LLVM, the normal JIT compiled versions are used.
5295 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5296 * - each bblock should end with a branch
5297 * - setting the return value, making cfg->ret non-volatile
5298 * - avoid some transformations in the JIT which make it harder for us to generate
5300 * - use pointer types to help optimizations.