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;
43 LLVMExecutionEngineRef ee;
47 * Information associated by the backend with mono basic blocks.
50 LLVMBasicBlockRef bblock, end_bblock;
51 LLVMValueRef finally_ind;
52 gboolean added, invoke_target;
54 * If this bblock is the start of a finally clause, this is a list of bblocks it
55 * needs to branch to in ENDFINALLY.
57 GSList *call_handler_return_bbs;
59 * If this bblock is the start of a finally clause, this is the bblock that
60 * CALL_HANDLER needs to branch to.
62 LLVMBasicBlockRef call_handler_target_bb;
63 /* The list of switch statements generated by ENDFINALLY instructions */
64 GSList *endfinally_switch_ins_list;
69 * Structure containing emit state
74 /* Maps method names to the corresponding LLVMValueRef */
75 GHashTable *emitted_method_decls;
79 MonoLLVMModule *lmodule;
82 int sindex, default_index, ex_index;
83 LLVMBuilderRef builder;
84 LLVMValueRef *values, *addresses;
85 MonoType **vreg_cli_types;
87 MonoMethodSignature *sig;
89 GHashTable *region_to_handler;
90 LLVMBuilderRef alloca_builder;
91 LLVMValueRef last_alloca;
92 LLVMValueRef rgctx_arg;
93 LLVMTypeRef *vreg_types;
95 gboolean *unreachable;
97 LLVMValueRef imt_rgctx_loc;
98 GHashTable *llvm_types;
106 MonoBasicBlock *in_bb;
111 * Instruction metadata
112 * This is the same as ins_info, but LREG != IREG.
120 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
121 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
128 /* keep in sync with the enum in mini.h */
131 #include "mini-ops.h"
136 #if SIZEOF_VOID_P == 4
137 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
139 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
142 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
145 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
147 #define TRACE_FAILURE(msg)
151 #define IS_TARGET_X86 1
153 #define IS_TARGET_X86 0
157 #define IS_TARGET_AMD64 1
159 #define IS_TARGET_AMD64 0
162 #define LLVM_FAILURE(ctx, reason) do { \
163 TRACE_FAILURE (reason); \
164 (ctx)->cfg->exception_message = g_strdup (reason); \
165 (ctx)->cfg->disable_llvm = TRUE; \
169 #define CHECK_FAILURE(ctx) do { \
170 if ((ctx)->cfg->disable_llvm) \
174 static LLVMIntPredicate cond_to_llvm_cond [] = {
187 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
200 static MonoNativeTlsKey current_cfg_tls_id;
202 static MonoLLVMModule aot_module;
203 static int memset_param_count, memcpy_param_count;
204 static const char *memset_func_name;
205 static const char *memcpy_func_name;
207 static void init_jit_module (MonoDomain *domain);
212 * The LLVM type with width == sizeof (gpointer)
217 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
223 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
229 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
235 * Return the size of the LLVM representation of the vtype T.
238 get_vtype_size (MonoType *t)
242 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
244 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
251 * simd_class_to_llvm_type:
253 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
256 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
258 if (!strcmp (klass->name, "Vector2d")) {
259 return LLVMVectorType (LLVMDoubleType (), 2);
260 } else if (!strcmp (klass->name, "Vector2l")) {
261 return LLVMVectorType (LLVMInt64Type (), 2);
262 } else if (!strcmp (klass->name, "Vector2ul")) {
263 return LLVMVectorType (LLVMInt64Type (), 2);
264 } else if (!strcmp (klass->name, "Vector4i")) {
265 return LLVMVectorType (LLVMInt32Type (), 4);
266 } else if (!strcmp (klass->name, "Vector4ui")) {
267 return LLVMVectorType (LLVMInt32Type (), 4);
268 } else if (!strcmp (klass->name, "Vector4f")) {
269 return LLVMVectorType (LLVMFloatType (), 4);
270 } else if (!strcmp (klass->name, "Vector8s")) {
271 return LLVMVectorType (LLVMInt16Type (), 8);
272 } else if (!strcmp (klass->name, "Vector8us")) {
273 return LLVMVectorType (LLVMInt16Type (), 8);
274 } else if (!strcmp (klass->name, "Vector16sb")) {
275 return LLVMVectorType (LLVMInt8Type (), 16);
276 } else if (!strcmp (klass->name, "Vector16b")) {
277 return LLVMVectorType (LLVMInt8Type (), 16);
279 printf ("%s\n", klass->name);
285 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
286 static inline G_GNUC_UNUSED LLVMTypeRef
287 type_to_simd_type (int type)
291 return LLVMVectorType (LLVMInt8Type (), 16);
293 return LLVMVectorType (LLVMInt16Type (), 8);
295 return LLVMVectorType (LLVMInt32Type (), 4);
297 return LLVMVectorType (LLVMInt64Type (), 2);
299 return LLVMVectorType (LLVMDoubleType (), 2);
301 return LLVMVectorType (LLVMFloatType (), 4);
303 g_assert_not_reached ();
311 * Return the LLVM type corresponding to T.
314 type_to_llvm_type (EmitContext *ctx, MonoType *t)
317 return LLVMPointerType (LLVMInt8Type (), 0);
320 return LLVMVoidType ();
322 return LLVMInt8Type ();
324 return LLVMInt16Type ();
326 return LLVMInt32Type ();
328 return LLVMInt8Type ();
330 return LLVMInt16Type ();
332 return LLVMInt32Type ();
333 case MONO_TYPE_BOOLEAN:
334 return LLVMInt8Type ();
337 return LLVMInt64Type ();
339 return LLVMInt16Type ();
341 return LLVMFloatType ();
343 return LLVMDoubleType ();
346 return IntPtrType ();
347 case MONO_TYPE_OBJECT:
348 case MONO_TYPE_CLASS:
349 case MONO_TYPE_ARRAY:
350 case MONO_TYPE_SZARRAY:
351 case MONO_TYPE_STRING:
353 return ObjRefType ();
356 /* Because of generic sharing */
357 return ObjRefType ();
358 case MONO_TYPE_GENERICINST:
359 if (!mono_type_generic_inst_is_valuetype (t))
360 return ObjRefType ();
362 case MONO_TYPE_VALUETYPE:
363 case MONO_TYPE_TYPEDBYREF: {
367 klass = mono_class_from_mono_type (t);
369 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
370 return simd_class_to_llvm_type (ctx, klass);
373 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
375 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
378 LLVMTypeRef *eltypes;
381 size = get_vtype_size (t);
383 eltypes = g_new (LLVMTypeRef, size);
384 for (i = 0; i < size; ++i)
385 eltypes [i] = LLVMInt8Type ();
387 name = mono_type_full_name (&klass->byval_arg);
388 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
389 LLVMStructSetBody (ltype, eltypes, size, FALSE);
390 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
398 printf ("X: %d\n", t->type);
399 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
400 ctx->cfg->disable_llvm = TRUE;
408 * Return whenever T is an unsigned int type.
411 type_is_unsigned (EmitContext *ctx, MonoType *t)
427 * type_to_llvm_arg_type:
429 * Same as type_to_llvm_type, but treat i8/i16 as i32.
432 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
434 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
436 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
438 * LLVM generates code which only sets the lower bits, while JITted
439 * code expects all the bits to be set.
441 ptype = LLVMInt32Type ();
448 * llvm_type_to_stack_type:
450 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
453 static G_GNUC_UNUSED LLVMTypeRef
454 llvm_type_to_stack_type (LLVMTypeRef type)
458 if (type == LLVMInt8Type ())
459 return LLVMInt32Type ();
460 else if (type == LLVMInt16Type ())
461 return LLVMInt32Type ();
462 else if (type == LLVMFloatType ())
463 return LLVMDoubleType ();
469 * regtype_to_llvm_type:
471 * Return the LLVM type corresponding to the regtype C used in instruction
475 regtype_to_llvm_type (char c)
479 return LLVMInt32Type ();
481 return LLVMInt64Type ();
483 return LLVMDoubleType ();
492 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
495 op_to_llvm_type (int opcode)
500 return LLVMInt8Type ();
503 return LLVMInt8Type ();
506 return LLVMInt16Type ();
509 return LLVMInt16Type ();
512 return LLVMInt32Type ();
515 return LLVMInt32Type ();
517 return LLVMInt64Type ();
519 return LLVMFloatType ();
521 return LLVMDoubleType ();
523 return LLVMInt64Type ();
525 return LLVMInt32Type ();
527 return LLVMInt64Type ();
530 return LLVMInt8Type ();
533 return LLVMInt16Type ();
536 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
543 return LLVMInt32Type ();
550 return LLVMInt64Type ();
552 printf ("%s\n", mono_inst_name (opcode));
553 g_assert_not_reached ();
559 * load_store_to_llvm_type:
561 * Return the size/sign/zero extension corresponding to the load/store opcode
565 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
571 case OP_LOADI1_MEMBASE:
572 case OP_STOREI1_MEMBASE_REG:
573 case OP_STOREI1_MEMBASE_IMM:
576 return LLVMInt8Type ();
577 case OP_LOADU1_MEMBASE:
581 return LLVMInt8Type ();
582 case OP_LOADI2_MEMBASE:
583 case OP_STOREI2_MEMBASE_REG:
584 case OP_STOREI2_MEMBASE_IMM:
587 return LLVMInt16Type ();
588 case OP_LOADU2_MEMBASE:
592 return LLVMInt16Type ();
593 case OP_LOADI4_MEMBASE:
594 case OP_LOADU4_MEMBASE:
597 case OP_STOREI4_MEMBASE_REG:
598 case OP_STOREI4_MEMBASE_IMM:
600 return LLVMInt32Type ();
601 case OP_LOADI8_MEMBASE:
603 case OP_STOREI8_MEMBASE_REG:
604 case OP_STOREI8_MEMBASE_IMM:
606 return LLVMInt64Type ();
607 case OP_LOADR4_MEMBASE:
608 case OP_STORER4_MEMBASE_REG:
610 return LLVMFloatType ();
611 case OP_LOADR8_MEMBASE:
612 case OP_STORER8_MEMBASE_REG:
614 return LLVMDoubleType ();
615 case OP_LOAD_MEMBASE:
617 case OP_STORE_MEMBASE_REG:
618 case OP_STORE_MEMBASE_IMM:
619 *size = sizeof (gpointer);
620 return IntPtrType ();
622 g_assert_not_reached ();
630 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
633 ovf_op_to_intrins (int opcode)
637 return "llvm.sadd.with.overflow.i32";
639 return "llvm.uadd.with.overflow.i32";
641 return "llvm.ssub.with.overflow.i32";
643 return "llvm.usub.with.overflow.i32";
645 return "llvm.smul.with.overflow.i32";
647 return "llvm.umul.with.overflow.i32";
649 return "llvm.sadd.with.overflow.i64";
651 return "llvm.uadd.with.overflow.i64";
653 return "llvm.ssub.with.overflow.i64";
655 return "llvm.usub.with.overflow.i64";
657 return "llvm.smul.with.overflow.i64";
659 return "llvm.umul.with.overflow.i64";
661 g_assert_not_reached ();
667 simd_op_to_intrins (int opcode)
670 #if defined(TARGET_X86) || defined(TARGET_AMD64)
672 return "llvm.x86.sse2.min.pd";
674 return "llvm.x86.sse.min.ps";
676 return "llvm.x86.sse41.pminud";
678 return "llvm.x86.sse41.pminuw";
680 return "llvm.x86.sse2.pminu.b";
682 return "llvm.x86.sse2.pmins.w";
684 return "llvm.x86.sse2.max.pd";
686 return "llvm.x86.sse.max.ps";
688 return "llvm.x86.sse3.hadd.pd";
690 return "llvm.x86.sse3.hadd.ps";
692 return "llvm.x86.sse3.hsub.pd";
694 return "llvm.x86.sse3.hsub.ps";
696 return "llvm.x86.sse41.pmaxud";
698 return "llvm.x86.sse41.pmaxuw";
700 return "llvm.x86.sse2.pmaxu.b";
702 return "llvm.x86.sse3.addsub.ps";
704 return "llvm.x86.sse3.addsub.pd";
705 case OP_EXTRACT_MASK:
706 return "llvm.x86.sse2.pmovmskb.128";
709 return "llvm.x86.sse2.psrli.w";
712 return "llvm.x86.sse2.psrli.d";
715 return "llvm.x86.sse2.psrli.q";
718 return "llvm.x86.sse2.pslli.w";
721 return "llvm.x86.sse2.pslli.d";
724 return "llvm.x86.sse2.pslli.q";
727 return "llvm.x86.sse2.psrai.w";
730 return "llvm.x86.sse2.psrai.d";
732 return "llvm.x86.sse2.padds.b";
734 return "llvm.x86.sse2.padds.w";
736 return "llvm.x86.sse2.psubs.b";
738 return "llvm.x86.sse2.psubs.w";
739 case OP_PADDB_SAT_UN:
740 return "llvm.x86.sse2.paddus.b";
741 case OP_PADDW_SAT_UN:
742 return "llvm.x86.sse2.paddus.w";
743 case OP_PSUBB_SAT_UN:
744 return "llvm.x86.sse2.psubus.b";
745 case OP_PSUBW_SAT_UN:
746 return "llvm.x86.sse2.psubus.w";
748 return "llvm.x86.sse2.pavg.b";
750 return "llvm.x86.sse2.pavg.w";
752 return "llvm.x86.sse.sqrt.ps";
754 return "llvm.x86.sse2.sqrt.pd";
756 return "llvm.x86.sse.rsqrt.ps";
758 return "llvm.x86.sse.rcp.ps";
760 return "llvm.x86.sse2.cvtdq2pd";
762 return "llvm.x86.sse2.cvtdq2ps";
764 return "llvm.x86.sse2.cvtpd2dq";
766 return "llvm.x86.sse2.cvtps2dq";
768 return "llvm.x86.sse2.cvtpd2ps";
770 return "llvm.x86.sse2.cvtps2pd";
772 return "llvm.x86.sse2.cvttpd2dq";
774 return "llvm.x86.sse2.cvttps2dq";
776 return "llvm.x86.sse.cmp.ps";
778 return "llvm.x86.sse2.cmp.pd";
780 return "llvm.x86.sse2.packsswb.128";
782 return "llvm.x86.sse2.packssdw.128";
784 return "llvm.x86.sse2.packuswb.128";
786 return "llvm.x86.sse41.packusdw";
788 return "llvm.x86.sse2.pmulh.w";
789 case OP_PMULW_HIGH_UN:
790 return "llvm.x86.sse2.pmulhu.w";
793 g_assert_not_reached ();
799 simd_op_to_llvm_type (int opcode)
801 #if defined(TARGET_X86) || defined(TARGET_AMD64)
805 return type_to_simd_type (MONO_TYPE_R8);
808 return type_to_simd_type (MONO_TYPE_I8);
811 return type_to_simd_type (MONO_TYPE_I4);
816 return type_to_simd_type (MONO_TYPE_I2);
820 return type_to_simd_type (MONO_TYPE_I1);
822 return type_to_simd_type (MONO_TYPE_R4);
825 return type_to_simd_type (MONO_TYPE_I4);
829 return type_to_simd_type (MONO_TYPE_R8);
833 return type_to_simd_type (MONO_TYPE_R4);
834 case OP_EXTRACT_MASK:
835 return type_to_simd_type (MONO_TYPE_I1);
841 return type_to_simd_type (MONO_TYPE_R4);
844 return type_to_simd_type (MONO_TYPE_R8);
846 g_assert_not_reached ();
857 * Return the LLVM basic block corresponding to BB.
859 static LLVMBasicBlockRef
860 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
862 char bb_name_buf [128];
865 if (ctx->bblocks [bb->block_num].bblock == NULL) {
866 if (bb->flags & BB_EXCEPTION_HANDLER) {
867 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
868 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
869 bb_name = bb_name_buf;
870 } else if (bb->block_num < 256) {
871 if (!ctx->lmodule->bb_names) {
872 ctx->lmodule->bb_names_len = 256;
873 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
875 if (!ctx->lmodule->bb_names [bb->block_num]) {
878 n = g_strdup_printf ("BB%d", bb->block_num);
879 mono_memory_barrier ();
880 ctx->lmodule->bb_names [bb->block_num] = n;
882 bb_name = ctx->lmodule->bb_names [bb->block_num];
884 sprintf (bb_name_buf, "BB%d", bb->block_num);
885 bb_name = bb_name_buf;
888 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
889 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
892 return ctx->bblocks [bb->block_num].bblock;
898 * Return the last LLVM bblock corresponding to BB.
899 * This might not be equal to the bb returned by get_bb () since we need to generate
900 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
902 static LLVMBasicBlockRef
903 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
906 return ctx->bblocks [bb->block_num].end_bblock;
909 static LLVMBasicBlockRef
910 gen_bb (EmitContext *ctx, const char *prefix)
914 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
915 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
921 * Return the target of the patch identified by TYPE and TARGET.
924 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
928 memset (&ji, 0, sizeof (ji));
930 ji.data.target = target;
932 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
938 * Emit code to convert the LLVM value V to DTYPE.
941 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
943 LLVMTypeRef stype = LLVMTypeOf (v);
945 if (stype != dtype) {
946 gboolean ext = FALSE;
949 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
951 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
953 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
957 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
959 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
960 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
963 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
964 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
965 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
966 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
967 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
968 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
969 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
970 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
972 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
973 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
974 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
975 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
976 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
977 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
979 if (mono_arch_is_soft_float ()) {
980 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
981 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
982 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
983 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
986 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
987 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
990 LLVMDumpValue (LLVMConstNull (dtype));
991 g_assert_not_reached ();
999 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1001 return convert_full (ctx, v, dtype, FALSE);
1005 * emit_volatile_load:
1007 * If vreg is volatile, emit a load from its address.
1010 emit_volatile_load (EmitContext *ctx, int vreg)
1014 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1015 t = ctx->vreg_cli_types [vreg];
1016 if (t && !t->byref) {
1018 * Might have to zero extend since llvm doesn't have
1021 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1022 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1023 else if (t->type == MONO_TYPE_U8)
1024 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1031 * emit_volatile_store:
1033 * If VREG is volatile, emit a store from its value to its address.
1036 emit_volatile_store (EmitContext *ctx, int vreg)
1038 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1040 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1041 g_assert (ctx->addresses [vreg]);
1042 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1048 * Maps parameter indexes in the original signature to parameter indexes
1049 * in the LLVM signature.
1052 /* The indexes of various special arguments in the LLVM signature */
1053 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1057 * sig_to_llvm_sig_full:
1059 * Return the LLVM signature corresponding to the mono signature SIG using the
1060 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1063 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1066 LLVMTypeRef ret_type;
1067 LLVMTypeRef *param_types = NULL;
1069 int i, j, pindex, vret_arg_pindex = 0;
1071 gboolean vretaddr = FALSE;
1074 memset (sinfo, 0, sizeof (LLVMSigInfo));
1076 ret_type = type_to_llvm_type (ctx, sig->ret);
1077 CHECK_FAILURE (ctx);
1079 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1080 /* LLVM models this by returning an aggregate value */
1081 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1082 LLVMTypeRef members [2];
1084 members [0] = IntPtrType ();
1085 ret_type = LLVMStructType (members, 1, FALSE);
1087 g_assert_not_reached ();
1089 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1090 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1092 ret_type = LLVMVoidType ();
1095 pindexes = g_new0 (int, sig->param_count);
1096 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1098 if (cinfo && cinfo->rgctx_arg) {
1100 sinfo->rgctx_arg_pindex = pindex;
1101 param_types [pindex] = ctx->lmodule->ptr_type;
1104 if (cinfo && cinfo->imt_arg) {
1106 sinfo->imt_arg_pindex = pindex;
1107 param_types [pindex] = ctx->lmodule->ptr_type;
1111 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1112 vret_arg_pindex = pindex;
1113 if (cinfo->vret_arg_index == 1) {
1114 /* Add the slots consumed by the first argument */
1115 LLVMArgInfo *ainfo = &cinfo->args [0];
1116 switch (ainfo->storage) {
1117 case LLVMArgVtypeInReg:
1118 for (j = 0; j < 2; ++j) {
1119 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1129 sinfo->vret_arg_pindex = vret_arg_pindex;
1132 if (vretaddr && vret_arg_pindex == pindex)
1133 param_types [pindex ++] = IntPtrType ();
1136 sinfo->this_arg_pindex = pindex;
1137 param_types [pindex ++] = ThisType ();
1139 if (vretaddr && vret_arg_pindex == pindex)
1140 param_types [pindex ++] = IntPtrType ();
1141 for (i = 0; i < sig->param_count; ++i) {
1142 if (vretaddr && vret_arg_pindex == pindex)
1143 param_types [pindex ++] = IntPtrType ();
1144 pindexes [i] = pindex;
1145 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1146 for (j = 0; j < 2; ++j) {
1147 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1149 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1154 g_assert_not_reached ();
1157 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1158 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1159 CHECK_FAILURE (ctx);
1160 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1163 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1166 if (vretaddr && vret_arg_pindex == pindex)
1167 param_types [pindex ++] = IntPtrType ();
1169 CHECK_FAILURE (ctx);
1171 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1172 g_free (param_types);
1175 sinfo->pindexes = pindexes;
1183 g_free (param_types);
1189 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1191 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1195 * LLVMFunctionType1:
1197 * Create an LLVM function type from the arguments.
1199 static G_GNUC_UNUSED LLVMTypeRef
1200 LLVMFunctionType1(LLVMTypeRef ReturnType,
1201 LLVMTypeRef ParamType1,
1204 LLVMTypeRef param_types [1];
1206 param_types [0] = ParamType1;
1208 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1212 * LLVMFunctionType2:
1214 * Create an LLVM function type from the arguments.
1216 static G_GNUC_UNUSED LLVMTypeRef
1217 LLVMFunctionType2(LLVMTypeRef ReturnType,
1218 LLVMTypeRef ParamType1,
1219 LLVMTypeRef ParamType2,
1222 LLVMTypeRef param_types [2];
1224 param_types [0] = ParamType1;
1225 param_types [1] = ParamType2;
1227 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1231 * LLVMFunctionType3:
1233 * Create an LLVM function type from the arguments.
1235 static G_GNUC_UNUSED LLVMTypeRef
1236 LLVMFunctionType3(LLVMTypeRef ReturnType,
1237 LLVMTypeRef ParamType1,
1238 LLVMTypeRef ParamType2,
1239 LLVMTypeRef ParamType3,
1242 LLVMTypeRef param_types [3];
1244 param_types [0] = ParamType1;
1245 param_types [1] = ParamType2;
1246 param_types [2] = ParamType3;
1248 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1254 * Create an LLVM builder and remember it so it can be freed later.
1256 static LLVMBuilderRef
1257 create_builder (EmitContext *ctx)
1259 LLVMBuilderRef builder = LLVMCreateBuilder ();
1261 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1267 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1269 char *callee_name = mono_aot_get_plt_symbol (type, data);
1270 LLVMValueRef callee;
1275 if (ctx->cfg->compile_aot)
1276 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1277 mono_add_patch_info (ctx->cfg, 0, type, data);
1280 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1282 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1284 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1286 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1293 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1295 MonoMethodHeader *header = cfg->header;
1296 MonoExceptionClause *clause;
1300 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1301 return (bb->region >> 8) - 1;
1304 for (i = 0; i < header->num_clauses; ++i) {
1305 clause = &header->clauses [i];
1307 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1315 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1317 LLVMValueRef md_arg;
1320 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1321 md_arg = LLVMMDString ("mono", 4);
1322 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1326 set_invariant_load_flag (LLVMValueRef v)
1328 LLVMValueRef md_arg;
1330 const char *flag_name;
1332 // FIXME: Cache this
1333 flag_name = "invariant.load";
1334 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1335 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1336 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1342 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1346 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1348 MonoCompile *cfg = ctx->cfg;
1350 LLVMBuilderRef builder = *builder_ref;
1353 clause_index = get_handler_clause (cfg, bb);
1355 if (clause_index != -1) {
1356 MonoMethodHeader *header = cfg->header;
1357 MonoExceptionClause *ec = &header->clauses [clause_index];
1358 MonoBasicBlock *tblock;
1359 LLVMBasicBlockRef ex_bb, noex_bb;
1362 * Have to use an invoke instead of a call, branching to the
1363 * handler bblock of the clause containing this bblock.
1366 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1368 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1371 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1373 ex_bb = get_bb (ctx, tblock);
1375 noex_bb = gen_bb (ctx, "NOEX_BB");
1378 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1380 builder = ctx->builder = create_builder (ctx);
1381 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1383 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1385 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1386 ctx->builder = builder;
1389 *builder_ref = ctx->builder;
1395 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1397 const char *intrins_name;
1398 LLVMValueRef args [16], res;
1399 LLVMTypeRef addr_type;
1401 if (is_faulting && bb->region != -1) {
1403 * We handle loads which can fault by calling a mono specific intrinsic
1404 * using an invoke, so they are handled properly inside try blocks.
1405 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1406 * are marked with IntrReadArgMem.
1410 intrins_name = "llvm.mono.load.i8.p0i8";
1413 intrins_name = "llvm.mono.load.i16.p0i16";
1416 intrins_name = "llvm.mono.load.i32.p0i32";
1419 intrins_name = "llvm.mono.load.i64.p0i64";
1422 g_assert_not_reached ();
1425 addr_type = LLVMTypeOf (addr);
1426 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1427 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1430 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1431 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1432 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1434 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1435 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1436 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1437 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1444 * We emit volatile loads for loads which can fault, because otherwise
1445 * LLVM will generate invalid code when encountering a load from a
1448 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1450 /* Mark it with a custom metadata */
1453 set_metadata_flag (res, "mono.faulting.load");
1461 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1463 const char *intrins_name;
1464 LLVMValueRef args [16];
1466 if (is_faulting && bb->region != -1) {
1469 intrins_name = "llvm.mono.store.i8.p0i8";
1472 intrins_name = "llvm.mono.store.i16.p0i16";
1475 intrins_name = "llvm.mono.store.i32.p0i32";
1478 intrins_name = "llvm.mono.store.i64.p0i64";
1481 g_assert_not_reached ();
1484 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1485 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1486 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1491 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1492 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1493 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1495 LLVMBuildStore (*builder_ref, value, addr);
1500 * emit_cond_system_exception:
1502 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1503 * Might set the ctx exception.
1506 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1508 LLVMBasicBlockRef ex_bb, noex_bb;
1509 LLVMBuilderRef builder;
1510 MonoClass *exc_class;
1511 LLVMValueRef args [2];
1513 ex_bb = gen_bb (ctx, "EX_BB");
1514 noex_bb = gen_bb (ctx, "NOEX_BB");
1516 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1518 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1519 g_assert (exc_class);
1521 /* Emit exception throwing code */
1522 builder = create_builder (ctx);
1523 LLVMPositionBuilderAtEnd (builder, ex_bb);
1525 if (!ctx->lmodule->throw_corlib_exception) {
1526 LLVMValueRef callee;
1528 const char *icall_name;
1530 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1531 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1532 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1533 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1534 /* This will become i8* */
1535 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1536 sig = sig_to_llvm_sig (ctx, throw_sig);
1538 if (ctx->cfg->compile_aot) {
1539 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1541 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1544 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1545 * - On x86, LLVM generated code doesn't push the arguments
1546 * - The trampoline takes the throw address as an arguments, not a pc offset.
1548 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1551 mono_memory_barrier ();
1552 ctx->lmodule->throw_corlib_exception = callee;
1555 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1556 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1558 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1561 * The LLVM mono branch contains changes so a block address can be passed as an
1562 * argument to a call.
1564 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1565 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1567 LLVMBuildUnreachable (builder);
1569 ctx->builder = create_builder (ctx);
1570 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1572 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1579 * emit_reg_to_vtype:
1581 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1584 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1588 size = get_vtype_size (t);
1590 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1591 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1594 for (j = 0; j < 2; ++j) {
1595 LLVMValueRef index [2], addr;
1596 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1597 LLVMTypeRef part_type;
1599 if (ainfo->pair_storage [j] == LLVMArgNone)
1602 part_type = LLVMIntType (part_size * 8);
1603 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1604 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1605 addr = LLVMBuildGEP (builder, address, index, 1, "");
1607 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1608 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1609 addr = LLVMBuildGEP (builder, address, index, 2, "");
1611 switch (ainfo->pair_storage [j]) {
1613 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1618 g_assert_not_reached ();
1621 size -= sizeof (gpointer);
1626 * emit_vtype_to_reg:
1628 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1629 * into REGS, and the number of registers into NREGS.
1632 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1637 size = get_vtype_size (t);
1639 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1640 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1643 for (j = 0; j < 2; ++j) {
1644 LLVMValueRef index [2], addr;
1645 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1647 if (ainfo->pair_storage [j] == LLVMArgNone)
1650 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1651 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1652 addr = LLVMBuildGEP (builder, address, index, 1, "");
1654 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1655 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1656 addr = LLVMBuildGEP (builder, address, index, 2, "");
1658 switch (ainfo->pair_storage [j]) {
1660 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1665 g_assert_not_reached ();
1667 size -= sizeof (gpointer);
1674 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1677 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1678 * get executed every time control reaches them.
1680 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1682 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1683 return ctx->last_alloca;
1687 build_alloca (EmitContext *ctx, MonoType *t)
1689 MonoClass *k = mono_class_from_mono_type (t);
1692 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1695 align = mono_class_min_align (k);
1697 /* Sometimes align is not a power of 2 */
1698 while (mono_is_power_of_two (align) == -1)
1701 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1705 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1708 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1711 lmodule->used = g_ptr_array_sized_new (16);
1712 g_ptr_array_add (lmodule->used, global);
1716 emit_llvm_used (MonoLLVMModule *lmodule)
1718 LLVMModuleRef module = lmodule->module;
1719 LLVMTypeRef used_type;
1720 LLVMValueRef used, *used_elem;
1726 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1727 used = LLVMAddGlobal (module, used_type, "llvm.used");
1728 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1729 for (i = 0; i < lmodule->used->len; ++i)
1730 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1731 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1732 LLVMSetLinkage (used, LLVMAppendingLinkage);
1733 LLVMSetSection (used, "llvm.metadata");
1739 * Emit code to load/convert arguments.
1742 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1745 MonoCompile *cfg = ctx->cfg;
1746 MonoMethodSignature *sig = ctx->sig;
1747 LLVMCallInfo *linfo = ctx->linfo;
1750 ctx->alloca_builder = create_builder (ctx);
1753 * Handle indirect/volatile variables by allocating memory for them
1754 * using 'alloca', and storing their address in a temporary.
1756 for (i = 0; i < cfg->num_varinfo; ++i) {
1757 MonoInst *var = cfg->varinfo [i];
1760 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1761 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1762 CHECK_FAILURE (ctx);
1763 /* Could be already created by an OP_VPHI */
1764 if (!ctx->addresses [var->dreg])
1765 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1766 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1770 for (i = 0; i < sig->param_count; ++i) {
1771 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1772 int reg = cfg->args [i + sig->hasthis]->dreg;
1774 if (ainfo->storage == LLVMArgVtypeInReg) {
1775 LLVMValueRef regs [2];
1778 * Emit code to save the argument from the registers to
1779 * the real argument.
1781 pindex = ctx->pindexes [i];
1782 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1783 if (ainfo->pair_storage [1] != LLVMArgNone)
1784 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1788 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1790 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1792 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1793 /* Treat these as normal values */
1794 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1796 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1797 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1799 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1800 /* Treat these as normal values */
1801 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1804 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1809 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1811 emit_volatile_store (ctx, cfg->args [0]->dreg);
1812 for (i = 0; i < sig->param_count; ++i)
1813 if (!mini_type_is_vtype (cfg, sig->params [i]))
1814 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1816 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1817 LLVMValueRef this_alloc;
1820 * The exception handling code needs the location where the this argument was
1821 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1822 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1823 * location into the LSDA.
1825 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1826 /* This volatile store will keep the alloca alive */
1827 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1829 set_metadata_flag (this_alloc, "mono.this");
1832 if (cfg->rgctx_var) {
1833 LLVMValueRef rgctx_alloc, store;
1836 * We handle the rgctx arg similarly to the this pointer.
1838 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1839 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1840 /* This volatile store will keep the alloca alive */
1841 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1843 set_metadata_flag (rgctx_alloc, "mono.this");
1847 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1848 * it needs to continue normally, or return back to the exception handling system.
1850 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1851 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1852 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1853 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1857 sprintf (name, "finally_ind_bb%d", bb->block_num);
1858 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1859 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1861 ctx->bblocks [bb->block_num].finally_ind = val;
1864 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1865 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1866 * LLVM optimizer passes.
1868 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1869 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1877 /* Have to export this for AOT */
1879 mono_personality (void);
1882 mono_personality (void)
1885 g_assert_not_reached ();
1889 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1891 MonoCompile *cfg = ctx->cfg;
1892 LLVMModuleRef module = ctx->module;
1893 LLVMValueRef *values = ctx->values;
1894 LLVMValueRef *addresses = ctx->addresses;
1895 MonoCallInst *call = (MonoCallInst*)ins;
1896 MonoMethodSignature *sig = call->signature;
1897 LLVMValueRef callee = NULL, lcall;
1899 LLVMCallInfo *cinfo;
1903 LLVMTypeRef llvm_sig;
1905 gboolean virtual, calli;
1906 LLVMBuilderRef builder = *builder_ref;
1909 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1910 LLVM_FAILURE (ctx, "non-default callconv");
1912 cinfo = call->cinfo;
1913 if (call->rgctx_arg_reg)
1914 cinfo->rgctx_arg = TRUE;
1915 if (call->imt_arg_reg)
1916 cinfo->imt_arg = TRUE;
1918 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1920 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1921 CHECK_FAILURE (ctx);
1923 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);
1924 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);
1926 /* FIXME: Avoid creating duplicate methods */
1928 if (ins->flags & MONO_INST_HAS_METHOD) {
1932 if (cfg->compile_aot) {
1933 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1935 LLVM_FAILURE (ctx, "can't encode patch");
1937 callee = LLVMAddFunction (module, "", llvm_sig);
1940 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1942 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1946 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1947 /* LLVM miscompiles async methods */
1948 LLVM_FAILURE (ctx, "#13734");
1951 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1957 memset (&ji, 0, sizeof (ji));
1958 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1959 ji.data.target = info->name;
1961 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1963 if (cfg->compile_aot) {
1964 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1966 LLVM_FAILURE (ctx, "can't encode patch");
1968 callee = LLVMAddFunction (module, "", llvm_sig);
1969 target = (gpointer)mono_icall_get_wrapper (info);
1970 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1973 if (cfg->compile_aot) {
1975 if (cfg->abs_patches) {
1976 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1978 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1980 LLVM_FAILURE (ctx, "can't encode patch");
1984 LLVM_FAILURE (ctx, "aot");
1986 callee = LLVMAddFunction (module, "", llvm_sig);
1988 if (cfg->abs_patches) {
1989 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1992 * FIXME: Some trampolines might have
1993 * their own calling convention on some platforms.
1995 #ifndef TARGET_AMD64
1996 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)
1997 LLVM_FAILURE (ctx, "trampoline with own cconv");
1999 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2000 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2004 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2010 int size = sizeof (gpointer);
2013 g_assert (ins->inst_offset % size == 0);
2014 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2016 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2018 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2020 if (ins->flags & MONO_INST_HAS_METHOD) {
2025 * Collect and convert arguments
2027 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2028 len = sizeof (LLVMValueRef) * nargs;
2029 args = alloca (len);
2030 memset (args, 0, len);
2031 l = call->out_ireg_args;
2033 if (call->rgctx_arg_reg) {
2034 g_assert (values [call->rgctx_arg_reg]);
2035 g_assert (sinfo.rgctx_arg_pindex < nargs);
2037 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2038 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2039 * it using a volatile load.
2042 if (!ctx->imt_rgctx_loc)
2043 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2044 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2045 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2047 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2050 if (call->imt_arg_reg) {
2051 g_assert (values [call->imt_arg_reg]);
2052 g_assert (sinfo.imt_arg_pindex < nargs);
2054 if (!ctx->imt_rgctx_loc)
2055 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2056 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2057 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2059 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2064 if (!addresses [call->inst.dreg])
2065 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2066 g_assert (sinfo.vret_arg_pindex < nargs);
2067 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2070 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2073 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2077 pindex = sinfo.this_arg_pindex;
2079 pindex = sinfo.pindexes [i - 1];
2081 pindex = sinfo.pindexes [i];
2084 regpair = (guint32)(gssize)(l->data);
2085 reg = regpair & 0xffffff;
2086 args [pindex] = values [reg];
2087 if (ainfo->storage == LLVMArgVtypeInReg) {
2089 LLVMValueRef regs [2];
2094 g_assert (addresses [reg]);
2096 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2097 for (j = 0; j < nregs; ++j)
2098 args [pindex ++] = regs [j];
2101 // FIXME: Get rid of the VMOVE
2102 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2103 g_assert (addresses [reg]);
2104 args [pindex] = addresses [reg];
2106 g_assert (args [pindex]);
2107 if (i == 0 && sig->hasthis)
2108 args [pindex] = convert (ctx, args [pindex], ThisType ());
2110 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2116 // FIXME: Align call sites
2122 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2125 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2127 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2128 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2130 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2131 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2133 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2135 if (call->rgctx_arg_reg)
2136 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2137 if (call->imt_arg_reg)
2138 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2140 /* Add byval attributes if needed */
2141 for (i = 0; i < sig->param_count; ++i) {
2142 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2144 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2145 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2150 * Convert the result
2152 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2153 LLVMValueRef regs [2];
2155 if (!addresses [ins->dreg])
2156 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2158 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2159 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2160 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2162 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2163 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2164 /* If the method returns an unsigned value, need to zext it */
2166 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));
2169 *builder_ref = ctx->builder;
2171 g_free (sinfo.pindexes);
2179 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2181 MonoCompile *cfg = ctx->cfg;
2182 MonoMethodSignature *sig = ctx->sig;
2183 LLVMValueRef method = ctx->lmethod;
2184 LLVMValueRef *values = ctx->values;
2185 LLVMValueRef *addresses = ctx->addresses;
2187 LLVMCallInfo *linfo = ctx->linfo;
2188 LLVMModuleRef module = ctx->module;
2189 BBInfo *bblocks = ctx->bblocks;
2191 LLVMBasicBlockRef cbb;
2192 LLVMBuilderRef builder, starting_builder;
2193 gboolean has_terminator;
2195 LLVMValueRef lhs, rhs;
2198 cbb = get_bb (ctx, bb);
2199 builder = create_builder (ctx);
2200 ctx->builder = builder;
2201 LLVMPositionBuilderAtEnd (builder, cbb);
2203 if (bb == cfg->bb_entry)
2204 emit_entry_bb (ctx, builder);
2205 CHECK_FAILURE (ctx);
2207 if (bb->flags & BB_EXCEPTION_HANDLER) {
2209 LLVMValueRef personality;
2210 LLVMBasicBlockRef target_bb;
2212 static gint32 mapping_inited;
2213 static int ti_generator;
2216 LLVMValueRef type_info;
2219 if (!bblocks [bb->block_num].invoke_target) {
2221 * LLVM asserts if llvm.eh.selector is called from a bblock which
2222 * doesn't have an invoke pointing at it.
2223 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2225 LLVM_FAILURE (ctx, "handler without invokes");
2228 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2230 if (cfg->compile_aot) {
2231 /* Use a dummy personality function */
2232 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2233 g_assert (personality);
2235 personality = LLVMGetNamedFunction (module, "mono_personality");
2236 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2237 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2240 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2242 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2245 * Create the type info
2247 sprintf (ti_name, "type_info_%d", ti_generator);
2250 if (cfg->compile_aot) {
2251 /* decode_eh_frame () in aot-runtime.c will decode this */
2252 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2253 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2256 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2258 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2261 * Enabling this causes llc to crash:
2262 * http://llvm.org/bugs/show_bug.cgi?id=6102
2264 //LLVM_FAILURE (ctx, "aot+clauses");
2266 // test_0_invalid_unbox_arrays () fails
2267 LLVM_FAILURE (ctx, "aot+clauses");
2271 * After the cfg mempool is freed, the type info will point to stale memory,
2272 * but this is not a problem, since we decode it once in exception_cb during
2275 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2276 *(gint32*)ti = clause_index;
2278 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2280 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2284 LLVMTypeRef members [2], ret_type;
2285 LLVMValueRef landing_pad;
2287 members [0] = i8ptr;
2288 members [1] = LLVMInt32Type ();
2289 ret_type = LLVMStructType (members, 2, FALSE);
2291 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2292 LLVMAddClause (landing_pad, type_info);
2294 /* Store the exception into the exvar */
2295 if (bb->in_scount == 1) {
2296 g_assert (bb->in_scount == 1);
2297 exvar = bb->in_stack [0];
2299 // FIXME: This is shared with filter clauses ?
2300 g_assert (!values [exvar->dreg]);
2302 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2303 emit_volatile_store (ctx, exvar->dreg);
2307 /* Start a new bblock which CALL_HANDLER can branch to */
2308 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2310 LLVMBuildBr (builder, target_bb);
2312 ctx->builder = builder = create_builder (ctx);
2313 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2315 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2319 has_terminator = FALSE;
2320 starting_builder = builder;
2321 for (ins = bb->code; ins; ins = ins->next) {
2322 const char *spec = LLVM_INS_INFO (ins->opcode);
2324 char dname_buf [128];
2327 if (nins > 5000 && builder == starting_builder) {
2328 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2329 LLVM_FAILURE (ctx, "basic block too long");
2333 /* There could be instructions after a terminator, skip them */
2336 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2337 sprintf (dname_buf, "t%d", ins->dreg);
2341 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2342 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2344 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2345 lhs = emit_volatile_load (ctx, ins->sreg1);
2347 /* It is ok for SETRET to have an uninitialized argument */
2348 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2349 LLVM_FAILURE (ctx, "sreg1");
2350 lhs = values [ins->sreg1];
2356 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2357 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2358 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2359 rhs = emit_volatile_load (ctx, ins->sreg2);
2361 if (!values [ins->sreg2])
2362 LLVM_FAILURE (ctx, "sreg2");
2363 rhs = values [ins->sreg2];
2369 //mono_print_ins (ins);
2370 switch (ins->opcode) {
2373 case OP_LIVERANGE_START:
2374 case OP_LIVERANGE_END:
2377 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2380 #if SIZEOF_VOID_P == 4
2381 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2383 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2387 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2390 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2392 case OP_DUMMY_ICONST:
2393 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2395 case OP_DUMMY_I8CONST:
2396 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2398 case OP_DUMMY_R8CONST:
2399 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2402 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2403 has_terminator = TRUE;
2409 LLVMBasicBlockRef new_bb;
2410 LLVMBuilderRef new_builder;
2412 // The default branch is already handled
2413 // FIXME: Handle it here
2415 /* Start new bblock */
2416 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2417 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2419 lhs = convert (ctx, lhs, LLVMInt32Type ());
2420 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2421 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2422 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2424 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2427 new_builder = create_builder (ctx);
2428 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2429 LLVMBuildUnreachable (new_builder);
2431 has_terminator = TRUE;
2432 g_assert (!ins->next);
2438 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2439 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2440 LLVMValueRef part1, retval;
2443 size = get_vtype_size (sig->ret);
2445 g_assert (addresses [ins->sreg1]);
2447 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2448 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2450 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2452 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2454 LLVMBuildRet (builder, retval);
2458 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2459 LLVMBuildRetVoid (builder);
2463 if (!lhs || ctx->is_dead [ins->sreg1]) {
2465 * The method did not set its return value, probably because it
2466 * ends with a throw.
2469 LLVMBuildRetVoid (builder);
2471 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2473 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2475 has_terminator = TRUE;
2481 case OP_ICOMPARE_IMM:
2482 case OP_LCOMPARE_IMM:
2483 case OP_COMPARE_IMM: {
2487 if (ins->next->opcode == OP_NOP)
2490 if (ins->next->opcode == OP_BR)
2491 /* The comparison result is not needed */
2494 rel = mono_opcode_to_cond (ins->next->opcode);
2496 if (ins->opcode == OP_ICOMPARE_IMM) {
2497 lhs = convert (ctx, lhs, LLVMInt32Type ());
2498 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2500 if (ins->opcode == OP_LCOMPARE_IMM) {
2501 lhs = convert (ctx, lhs, LLVMInt64Type ());
2502 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2504 if (ins->opcode == OP_LCOMPARE) {
2505 lhs = convert (ctx, lhs, LLVMInt64Type ());
2506 rhs = convert (ctx, rhs, LLVMInt64Type ());
2508 if (ins->opcode == OP_ICOMPARE) {
2509 lhs = convert (ctx, lhs, LLVMInt32Type ());
2510 rhs = convert (ctx, rhs, LLVMInt32Type ());
2514 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2515 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2516 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2517 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2520 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2521 if (ins->opcode == OP_FCOMPARE)
2522 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2523 else if (ins->opcode == OP_COMPARE_IMM) {
2524 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2525 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2527 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2528 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2529 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2530 /* The immediate is encoded in two fields */
2531 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2532 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2534 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2537 else if (ins->opcode == OP_COMPARE) {
2538 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2541 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2543 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2545 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2546 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2548 * If the target bb contains PHI instructions, LLVM requires
2549 * two PHI entries for this bblock, while we only generate one.
2550 * So convert this to an unconditional bblock. (bxc #171).
2552 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2554 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2556 has_terminator = TRUE;
2557 } else if (MONO_IS_SETCC (ins->next)) {
2558 sprintf (dname_buf, "t%d", ins->next->dreg);
2560 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2562 /* Add stores for volatile variables */
2563 emit_volatile_store (ctx, ins->next->dreg);
2564 } else if (MONO_IS_COND_EXC (ins->next)) {
2565 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2566 CHECK_FAILURE (ctx);
2567 builder = ctx->builder;
2569 LLVM_FAILURE (ctx, "next");
2583 rel = mono_opcode_to_cond (ins->opcode);
2585 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2586 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2594 gboolean empty = TRUE;
2596 /* Check that all input bblocks really branch to us */
2597 for (i = 0; i < bb->in_count; ++i) {
2598 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2599 ins->inst_phi_args [i + 1] = -1;
2605 /* LLVM doesn't like phi instructions with zero operands */
2606 ctx->is_dead [ins->dreg] = TRUE;
2610 /* Created earlier, insert it now */
2611 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2613 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2614 int sreg1 = ins->inst_phi_args [i + 1];
2618 * Count the number of times the incoming bblock branches to us,
2619 * since llvm requires a separate entry for each.
2621 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2622 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2625 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2626 if (switch_ins->inst_many_bb [j] == bb)
2633 /* Remember for later */
2634 for (j = 0; j < count; ++j) {
2635 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2638 node->in_bb = bb->in_bb [i];
2640 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);
2650 values [ins->dreg] = lhs;
2653 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2656 values [ins->dreg] = lhs;
2658 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2660 * This is added by the spilling pass in case of the JIT,
2661 * but we have to do it ourselves.
2663 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2697 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2698 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2700 switch (ins->opcode) {
2703 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2707 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2711 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2715 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2719 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2723 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2727 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2730 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2734 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2738 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2742 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2746 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2750 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2754 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2758 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2761 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2764 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2768 g_assert_not_reached ();
2775 case OP_IREM_UN_IMM:
2777 case OP_IDIV_UN_IMM:
2783 case OP_ISHR_UN_IMM:
2792 case OP_LSHR_UN_IMM:
2798 case OP_SHR_UN_IMM: {
2801 if (spec [MONO_INST_SRC1] == 'l') {
2802 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2804 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2807 #if SIZEOF_VOID_P == 4
2808 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2809 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2812 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2813 lhs = convert (ctx, lhs, IntPtrType ());
2814 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2815 switch (ins->opcode) {
2819 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2823 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2827 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2831 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2833 case OP_IDIV_UN_IMM:
2834 case OP_LDIV_UN_IMM:
2835 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2839 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2841 case OP_IREM_UN_IMM:
2842 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2847 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2851 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2855 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2860 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2865 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2867 case OP_ISHR_UN_IMM:
2868 /* This is used to implement conv.u4, so the lhs could be an i8 */
2869 lhs = convert (ctx, lhs, LLVMInt32Type ());
2870 imm = convert (ctx, imm, LLVMInt32Type ());
2871 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2873 case OP_LSHR_UN_IMM:
2875 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2878 g_assert_not_reached ();
2883 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2886 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2889 lhs = convert (ctx, lhs, LLVMDoubleType ());
2890 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2893 guint32 v = 0xffffffff;
2894 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2898 guint64 v = 0xffffffffffffffffLL;
2899 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2902 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2904 LLVMValueRef v1, v2;
2906 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2907 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2908 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2913 case OP_ICONV_TO_I1:
2914 case OP_ICONV_TO_I2:
2915 case OP_ICONV_TO_I4:
2916 case OP_ICONV_TO_U1:
2917 case OP_ICONV_TO_U2:
2918 case OP_ICONV_TO_U4:
2919 case OP_LCONV_TO_I1:
2920 case OP_LCONV_TO_I2:
2921 case OP_LCONV_TO_U1:
2922 case OP_LCONV_TO_U2:
2923 case OP_LCONV_TO_U4: {
2926 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);
2928 /* Have to do two casts since our vregs have type int */
2929 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2931 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2933 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2936 case OP_ICONV_TO_I8:
2937 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2939 case OP_ICONV_TO_U8:
2940 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2942 case OP_FCONV_TO_I4:
2943 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2945 case OP_FCONV_TO_I1:
2946 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2948 case OP_FCONV_TO_U1:
2949 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2951 case OP_FCONV_TO_I2:
2952 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2954 case OP_FCONV_TO_U2:
2955 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2957 case OP_FCONV_TO_I8:
2958 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2961 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2963 case OP_ICONV_TO_R8:
2964 case OP_LCONV_TO_R8:
2965 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2967 case OP_LCONV_TO_R_UN:
2968 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2970 #if SIZEOF_VOID_P == 4
2973 case OP_LCONV_TO_I4:
2974 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2976 case OP_ICONV_TO_R4:
2977 case OP_LCONV_TO_R4:
2978 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2979 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2981 case OP_FCONV_TO_R4:
2982 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2983 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2986 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2989 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2992 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2994 case OP_LOCALLOC_IMM: {
2997 guint32 size = ins->inst_imm;
2998 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3000 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3002 if (ins->flags & MONO_INST_INIT) {
3003 LLVMValueRef args [5];
3006 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3007 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3008 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3009 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3010 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3013 values [ins->dreg] = v;
3017 LLVMValueRef v, size;
3019 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), "");
3021 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3023 if (ins->flags & MONO_INST_INIT) {
3024 LLVMValueRef args [5];
3027 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3029 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3030 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3031 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3033 values [ins->dreg] = v;
3037 case OP_LOADI1_MEMBASE:
3038 case OP_LOADU1_MEMBASE:
3039 case OP_LOADI2_MEMBASE:
3040 case OP_LOADU2_MEMBASE:
3041 case OP_LOADI4_MEMBASE:
3042 case OP_LOADU4_MEMBASE:
3043 case OP_LOADI8_MEMBASE:
3044 case OP_LOADR4_MEMBASE:
3045 case OP_LOADR8_MEMBASE:
3046 case OP_LOAD_MEMBASE:
3054 LLVMValueRef base, index, addr;
3056 gboolean sext = FALSE, zext = FALSE;
3057 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3059 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3064 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)) {
3065 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3070 if (ins->inst_offset == 0) {
3072 } else if (ins->inst_offset % size != 0) {
3073 /* Unaligned load */
3074 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3075 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3077 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3078 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3082 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3084 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3086 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3088 * These will signal LLVM that these loads do not alias any stores, and
3089 * they can't fail, allowing them to be hoisted out of loops.
3091 set_invariant_load_flag (values [ins->dreg]);
3092 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3096 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3098 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3099 else if (ins->opcode == OP_LOADR4_MEMBASE)
3100 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3104 case OP_STOREI1_MEMBASE_REG:
3105 case OP_STOREI2_MEMBASE_REG:
3106 case OP_STOREI4_MEMBASE_REG:
3107 case OP_STOREI8_MEMBASE_REG:
3108 case OP_STORER4_MEMBASE_REG:
3109 case OP_STORER8_MEMBASE_REG:
3110 case OP_STORE_MEMBASE_REG: {
3112 LLVMValueRef index, addr;
3114 gboolean sext = FALSE, zext = FALSE;
3115 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3117 if (!values [ins->inst_destbasereg])
3118 LLVM_FAILURE (ctx, "inst_destbasereg");
3120 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3122 if (ins->inst_offset % size != 0) {
3123 /* Unaligned store */
3124 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3125 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3127 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3128 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3130 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3134 case OP_STOREI1_MEMBASE_IMM:
3135 case OP_STOREI2_MEMBASE_IMM:
3136 case OP_STOREI4_MEMBASE_IMM:
3137 case OP_STOREI8_MEMBASE_IMM:
3138 case OP_STORE_MEMBASE_IMM: {
3140 LLVMValueRef index, addr;
3142 gboolean sext = FALSE, zext = FALSE;
3143 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3145 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3147 if (ins->inst_offset % size != 0) {
3148 /* Unaligned store */
3149 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3150 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3152 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3153 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3155 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3160 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3162 case OP_OUTARG_VTRETADDR:
3169 case OP_VOIDCALL_MEMBASE:
3170 case OP_CALL_MEMBASE:
3171 case OP_LCALL_MEMBASE:
3172 case OP_FCALL_MEMBASE:
3173 case OP_VCALL_MEMBASE:
3174 case OP_VOIDCALL_REG:
3178 case OP_VCALL_REG: {
3179 process_call (ctx, bb, &builder, ins);
3180 CHECK_FAILURE (ctx);
3185 LLVMValueRef indexes [2];
3187 LLVMValueRef got_entry_addr;
3190 * FIXME: Can't allocate from the cfg mempool since that is freed if
3191 * the LLVM compile fails.
3193 ji = g_new0 (MonoJumpInfo, 1);
3194 ji->type = (MonoJumpInfoType)ins->inst_i1;
3195 ji->data.target = ins->inst_p0;
3197 ji = mono_aot_patch_info_dup (ji);
3199 ji->next = cfg->patch_info;
3200 cfg->patch_info = ji;
3202 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3203 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3205 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3206 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3207 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3209 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3210 set_invariant_load_flag (values [ins->dreg]);
3213 case OP_NOT_REACHED:
3214 LLVMBuildUnreachable (builder);
3215 has_terminator = TRUE;
3216 g_assert (bb->block_num < cfg->max_block_num);
3217 ctx->unreachable [bb->block_num] = TRUE;
3218 /* Might have instructions after this */
3220 MonoInst *next = ins->next;
3222 * FIXME: If later code uses the regs defined by these instructions,
3223 * compilation will fail.
3225 MONO_DELETE_INS (bb, next);
3229 MonoInst *var = ins->inst_p0;
3231 values [ins->dreg] = addresses [var->dreg];
3235 LLVMValueRef args [1];
3237 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3238 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3242 LLVMValueRef args [1];
3244 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3245 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3249 LLVMValueRef args [1];
3252 /* This no longer seems to happen */
3254 * LLVM optimizes sqrt(nan) into undefined in
3255 * lib/Analysis/ConstantFolding.cpp
3256 * Also, sqrt(NegativeInfinity) is optimized into 0.
3258 LLVM_FAILURE (ctx, "sqrt");
3260 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3261 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3265 LLVMValueRef args [1];
3267 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3268 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3282 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3283 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3285 switch (ins->opcode) {
3288 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3292 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3296 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3300 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3303 g_assert_not_reached ();
3306 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3309 case OP_ATOMIC_EXCHANGE_I4:
3310 case OP_ATOMIC_EXCHANGE_I8: {
3311 LLVMValueRef args [2];
3314 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3315 t = LLVMInt32Type ();
3317 t = LLVMInt64Type ();
3319 g_assert (ins->inst_offset == 0);
3321 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3322 args [1] = convert (ctx, rhs, t);
3324 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3327 case OP_ATOMIC_ADD_NEW_I4:
3328 case OP_ATOMIC_ADD_NEW_I8: {
3329 LLVMValueRef args [2];
3332 if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
3333 t = LLVMInt32Type ();
3335 t = LLVMInt64Type ();
3337 g_assert (ins->inst_offset == 0);
3339 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3340 args [1] = convert (ctx, rhs, t);
3341 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3344 case OP_ATOMIC_CAS_I4:
3345 case OP_ATOMIC_CAS_I8: {
3346 LLVMValueRef args [3];
3349 if (ins->opcode == OP_ATOMIC_CAS_I4)
3350 t = LLVMInt32Type ();
3352 t = LLVMInt64Type ();
3354 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3356 args [1] = convert (ctx, values [ins->sreg3], t);
3358 args [2] = convert (ctx, values [ins->sreg2], t);
3359 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3362 case OP_MEMORY_BARRIER: {
3363 mono_llvm_build_fence (builder);
3366 case OP_RELAXED_NOP: {
3367 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3368 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3375 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3377 // 257 == FS segment register
3378 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3380 // 256 == GS segment register
3381 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3384 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3385 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3386 /* See mono_amd64_emit_tls_get () */
3387 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3389 // 256 == GS segment register
3390 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3391 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3393 LLVM_FAILURE (ctx, "opcode tls-get");
3398 case OP_TLS_GET_REG: {
3399 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3400 /* See emit_tls_get_reg () */
3401 // 256 == GS segment register
3402 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3403 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3405 LLVM_FAILURE (ctx, "opcode tls-get");
3414 case OP_IADD_OVF_UN:
3416 case OP_ISUB_OVF_UN:
3418 case OP_IMUL_OVF_UN:
3419 #if SIZEOF_VOID_P == 8
3421 case OP_LADD_OVF_UN:
3423 case OP_LSUB_OVF_UN:
3425 case OP_LMUL_OVF_UN:
3428 LLVMValueRef args [2], val, ovf, func;
3430 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3431 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3432 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3434 val = LLVMBuildCall (builder, func, args, 2, "");
3435 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3436 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3437 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3438 CHECK_FAILURE (ctx);
3439 builder = ctx->builder;
3445 * We currently model them using arrays. Promotion to local vregs is
3446 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3447 * so we always have an entry in cfg->varinfo for them.
3448 * FIXME: Is this needed ?
3451 MonoClass *klass = ins->klass;
3452 LLVMValueRef args [5];
3456 LLVM_FAILURE (ctx, "!klass");
3460 if (!addresses [ins->dreg])
3461 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3462 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3463 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3464 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3466 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3467 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3468 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3471 case OP_DUMMY_VZERO:
3474 case OP_STOREV_MEMBASE:
3475 case OP_LOADV_MEMBASE:
3477 MonoClass *klass = ins->klass;
3478 LLVMValueRef src = NULL, dst, args [5];
3479 gboolean done = FALSE;
3483 LLVM_FAILURE (ctx, "!klass");
3487 if (mini_is_gsharedvt_klass (cfg, klass)) {
3489 LLVM_FAILURE (ctx, "gsharedvt");
3493 switch (ins->opcode) {
3494 case OP_STOREV_MEMBASE:
3495 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3496 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3497 /* Decomposed earlier */
3498 g_assert_not_reached ();
3501 if (!addresses [ins->sreg1]) {
3503 g_assert (values [ins->sreg1]);
3504 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));
3505 LLVMBuildStore (builder, values [ins->sreg1], dst);
3508 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3509 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3512 case OP_LOADV_MEMBASE:
3513 if (!addresses [ins->dreg])
3514 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3515 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3516 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3519 if (!addresses [ins->sreg1])
3520 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3521 if (!addresses [ins->dreg])
3522 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3523 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3524 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3527 g_assert_not_reached ();
3529 CHECK_FAILURE (ctx);
3536 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3537 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3539 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3540 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3541 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3544 case OP_LLVM_OUTARG_VT:
3545 if (!addresses [ins->sreg1]) {
3546 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3547 g_assert (values [ins->sreg1]);
3548 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3550 addresses [ins->dreg] = addresses [ins->sreg1];
3556 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3558 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3561 case OP_LOADX_MEMBASE: {
3562 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3565 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3566 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3569 case OP_STOREX_MEMBASE: {
3570 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3573 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3574 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3581 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3585 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3591 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3595 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3599 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3603 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3606 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3609 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3612 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3616 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3627 LLVMValueRef v = NULL;
3629 switch (ins->opcode) {
3634 t = LLVMVectorType (LLVMInt32Type (), 4);
3635 rt = LLVMVectorType (LLVMFloatType (), 4);
3641 t = LLVMVectorType (LLVMInt64Type (), 2);
3642 rt = LLVMVectorType (LLVMDoubleType (), 2);
3645 t = LLVMInt32Type ();
3646 rt = LLVMInt32Type ();
3647 g_assert_not_reached ();
3650 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3651 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3652 switch (ins->opcode) {
3655 v = LLVMBuildAnd (builder, lhs, rhs, "");
3659 v = LLVMBuildOr (builder, lhs, rhs, "");
3663 v = LLVMBuildXor (builder, lhs, rhs, "");
3667 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3670 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3694 case OP_PADDB_SAT_UN:
3695 case OP_PADDW_SAT_UN:
3696 case OP_PSUBB_SAT_UN:
3697 case OP_PSUBW_SAT_UN:
3705 case OP_PMULW_HIGH_UN: {
3706 LLVMValueRef args [2];
3711 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3718 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3722 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3730 case OP_EXTRACTX_U2:
3732 case OP_EXTRACT_U1: {
3734 gboolean zext = FALSE;
3736 t = simd_op_to_llvm_type (ins->opcode);
3738 switch (ins->opcode) {
3746 case OP_EXTRACTX_U2:
3751 t = LLVMInt32Type ();
3752 g_assert_not_reached ();
3755 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3756 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3758 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3767 case OP_EXPAND_R8: {
3768 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3769 LLVMValueRef mask [16], v;
3771 for (i = 0; i < 16; ++i)
3772 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3774 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3776 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3777 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3782 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3785 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3788 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3791 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3794 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3797 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3808 case OP_EXTRACT_MASK:
3815 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3817 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3821 case OP_ICONV_TO_R8_RAW:
3822 /* Same as OP_ICONV_TO_R8 */
3823 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3828 LLVMValueRef args [3];
3832 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3834 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3839 /* This is only used for implementing shifts by non-immediate */
3840 values [ins->dreg] = lhs;
3851 LLVMValueRef args [3];
3854 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3856 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3867 case OP_PSHLQ_REG: {
3868 LLVMValueRef args [3];
3871 args [1] = values [ins->sreg2];
3873 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3880 case OP_PSHUFLEW_LOW:
3881 case OP_PSHUFLEW_HIGH: {
3883 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3884 int i, mask_size = 0;
3885 int imask = ins->inst_c0;
3887 /* Convert the x86 shuffle mask to LLVM's */
3888 switch (ins->opcode) {
3891 mask [0] = ((imask >> 0) & 3);
3892 mask [1] = ((imask >> 2) & 3);
3893 mask [2] = ((imask >> 4) & 3) + 4;
3894 mask [3] = ((imask >> 6) & 3) + 4;
3895 v1 = values [ins->sreg1];
3896 v2 = values [ins->sreg2];
3900 mask [0] = ((imask >> 0) & 1);
3901 mask [1] = ((imask >> 1) & 1) + 2;
3902 v1 = values [ins->sreg1];
3903 v2 = values [ins->sreg2];
3905 case OP_PSHUFLEW_LOW:
3907 mask [0] = ((imask >> 0) & 3);
3908 mask [1] = ((imask >> 2) & 3);
3909 mask [2] = ((imask >> 4) & 3);
3910 mask [3] = ((imask >> 6) & 3);
3915 v1 = values [ins->sreg1];
3916 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3918 case OP_PSHUFLEW_HIGH:
3924 mask [4] = 4 + ((imask >> 0) & 3);
3925 mask [5] = 4 + ((imask >> 2) & 3);
3926 mask [6] = 4 + ((imask >> 4) & 3);
3927 mask [7] = 4 + ((imask >> 6) & 3);
3928 v1 = values [ins->sreg1];
3929 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3933 mask [0] = ((imask >> 0) & 3);
3934 mask [1] = ((imask >> 2) & 3);
3935 mask [2] = ((imask >> 4) & 3);
3936 mask [3] = ((imask >> 6) & 3);
3937 v1 = values [ins->sreg1];
3938 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3941 g_assert_not_reached ();
3943 for (i = 0; i < mask_size; ++i)
3944 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3946 values [ins->dreg] =
3947 LLVMBuildShuffleVector (builder, v1, v2,
3948 LLVMConstVector (mask_values, mask_size), dname);
3952 case OP_UNPACK_LOWB:
3953 case OP_UNPACK_LOWW:
3954 case OP_UNPACK_LOWD:
3955 case OP_UNPACK_LOWQ:
3956 case OP_UNPACK_LOWPS:
3957 case OP_UNPACK_LOWPD:
3958 case OP_UNPACK_HIGHB:
3959 case OP_UNPACK_HIGHW:
3960 case OP_UNPACK_HIGHD:
3961 case OP_UNPACK_HIGHQ:
3962 case OP_UNPACK_HIGHPS:
3963 case OP_UNPACK_HIGHPD: {
3965 LLVMValueRef mask_values [16];
3966 int i, mask_size = 0;
3967 gboolean low = FALSE;
3969 switch (ins->opcode) {
3970 case OP_UNPACK_LOWB:
3974 case OP_UNPACK_LOWW:
3978 case OP_UNPACK_LOWD:
3979 case OP_UNPACK_LOWPS:
3983 case OP_UNPACK_LOWQ:
3984 case OP_UNPACK_LOWPD:
3988 case OP_UNPACK_HIGHB:
3991 case OP_UNPACK_HIGHW:
3994 case OP_UNPACK_HIGHD:
3995 case OP_UNPACK_HIGHPS:
3998 case OP_UNPACK_HIGHQ:
3999 case OP_UNPACK_HIGHPD:
4003 g_assert_not_reached ();
4007 for (i = 0; i < (mask_size / 2); ++i) {
4009 mask [(i * 2) + 1] = mask_size + i;
4012 for (i = 0; i < (mask_size / 2); ++i) {
4013 mask [(i * 2)] = (mask_size / 2) + i;
4014 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4018 for (i = 0; i < mask_size; ++i)
4019 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4021 values [ins->dreg] =
4022 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4023 LLVMConstVector (mask_values, mask_size), dname);
4028 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4029 LLVMValueRef v, val;
4031 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4032 val = LLVMConstNull (t);
4033 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4034 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4036 values [ins->dreg] = val;
4040 case OP_DUPPS_HIGH: {
4041 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4042 LLVMValueRef v1, v2, val;
4045 if (ins->opcode == OP_DUPPS_LOW) {
4046 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4047 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4049 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4050 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4052 val = LLVMConstNull (t);
4053 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4054 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4055 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4056 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4058 values [ins->dreg] = val;
4068 * EXCEPTION HANDLING
4070 case OP_IMPLICIT_EXCEPTION:
4071 /* This marks a place where an implicit exception can happen */
4072 if (bb->region != -1)
4073 LLVM_FAILURE (ctx, "implicit-exception");
4077 MonoMethodSignature *throw_sig;
4078 LLVMValueRef callee, arg;
4079 gboolean rethrow = (ins->opcode == OP_RETHROW);
4080 const char *icall_name;
4082 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4083 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4086 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4087 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4088 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4089 if (cfg->compile_aot) {
4090 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4092 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4096 * LLVM doesn't push the exception argument, so we need a different
4099 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4101 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4105 mono_memory_barrier ();
4107 ctx->lmodule->rethrow = callee;
4109 ctx->lmodule->throw = callee;
4111 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4112 emit_call (ctx, bb, &builder, callee, &arg, 1);
4115 case OP_CALL_HANDLER: {
4117 * We don't 'call' handlers, but instead simply branch to them.
4118 * The code generated by ENDFINALLY will branch back to us.
4120 LLVMBasicBlockRef noex_bb;
4122 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4124 bb_list = info->call_handler_return_bbs;
4127 * Set the indicator variable for the finally clause.
4129 lhs = info->finally_ind;
4131 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4133 /* Branch to the finally clause */
4134 LLVMBuildBr (builder, info->call_handler_target_bb);
4136 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4137 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4139 builder = ctx->builder = create_builder (ctx);
4140 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4142 bblocks [bb->block_num].end_bblock = noex_bb;
4145 case OP_START_HANDLER: {
4148 case OP_ENDFINALLY: {
4149 LLVMBasicBlockRef resume_bb;
4150 MonoBasicBlock *handler_bb;
4151 LLVMValueRef val, switch_ins, callee;
4155 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4156 g_assert (handler_bb);
4157 info = &bblocks [handler_bb->block_num];
4158 lhs = info->finally_ind;
4161 bb_list = info->call_handler_return_bbs;
4163 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4165 /* Load the finally variable */
4166 val = LLVMBuildLoad (builder, lhs, "");
4168 /* Reset the variable */
4169 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4171 /* Branch to either resume_bb, or to the bblocks in bb_list */
4172 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4174 * The other targets are added at the end to handle OP_CALL_HANDLER
4175 * opcodes processed later.
4177 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4179 builder = ctx->builder = create_builder (ctx);
4180 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4182 if (ctx->cfg->compile_aot) {
4183 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4185 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4187 LLVMBuildCall (builder, callee, NULL, 0, "");
4189 LLVMBuildUnreachable (builder);
4190 has_terminator = TRUE;
4196 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4197 LLVM_FAILURE (ctx, reason);
4202 /* Convert the value to the type required by phi nodes */
4203 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4204 if (!values [ins->dreg])
4206 values [ins->dreg] = addresses [ins->dreg];
4208 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4211 /* Add stores for volatile variables */
4212 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4213 emit_volatile_store (ctx, ins->dreg);
4216 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4217 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4219 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4220 LLVMBuildRetVoid (builder);
4222 if (bb == cfg->bb_entry)
4223 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4232 * mono_llvm_check_method_supported:
4234 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4235 * compiling a method twice.
4238 mono_llvm_check_method_supported (MonoCompile *cfg)
4240 MonoMethodHeader *header = cfg->header;
4241 MonoExceptionClause *clause;
4244 if (cfg->method->save_lmf) {
4245 cfg->exception_message = g_strdup ("lmf");
4246 cfg->disable_llvm = TRUE;
4248 if (cfg->disable_llvm)
4252 for (i = 0; i < header->num_clauses; ++i) {
4253 clause = &header->clauses [i];
4255 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4257 * FIXME: Some tests still fail with nested clauses.
4259 cfg->exception_message = g_strdup ("nested clauses");
4260 cfg->disable_llvm = TRUE;
4264 if (cfg->disable_llvm)
4269 if (cfg->method->dynamic) {
4270 cfg->exception_message = g_strdup ("dynamic.");
4271 cfg->disable_llvm = TRUE;
4273 if (cfg->disable_llvm)
4278 * mono_llvm_emit_method:
4280 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4283 mono_llvm_emit_method (MonoCompile *cfg)
4286 MonoMethodSignature *sig;
4288 LLVMTypeRef method_type;
4289 LLVMValueRef method = NULL;
4291 LLVMValueRef *values;
4292 int i, max_block_num, bb_index;
4293 gboolean last = FALSE;
4294 GPtrArray *phi_values;
4295 LLVMCallInfo *linfo;
4297 LLVMModuleRef module;
4299 GPtrArray *bblock_list;
4300 MonoMethodHeader *header;
4301 MonoExceptionClause *clause;
4305 /* The code below might acquire the loader lock, so use it for global locking */
4306 mono_loader_lock ();
4308 /* Used to communicate with the callbacks */
4309 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4311 ctx = g_new0 (EmitContext, 1);
4313 ctx->mempool = cfg->mempool;
4316 * This maps vregs to the LLVM instruction defining them
4318 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4320 * This maps vregs for volatile variables to the LLVM instruction defining their
4323 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4324 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4325 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4326 phi_values = g_ptr_array_sized_new (256);
4328 * This signals whenever the vreg was defined by a phi node with no input vars
4329 * (i.e. all its input bblocks end with NOT_REACHABLE).
4331 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4332 /* Whenever the bblock is unreachable */
4333 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4335 bblock_list = g_ptr_array_sized_new (256);
4337 ctx->values = values;
4338 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4340 if (cfg->compile_aot) {
4341 ctx->lmodule = &aot_module;
4342 method_name = mono_aot_get_method_name (cfg);
4343 cfg->llvm_method_name = g_strdup (method_name);
4345 init_jit_module (cfg->domain);
4346 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4347 method_name = mono_method_full_name (cfg->method, TRUE);
4350 module = ctx->module = ctx->lmodule->module;
4353 LLVM_FAILURE (ctx, "gsharedvt");
4357 static int count = 0;
4360 if (g_getenv ("LLVM_COUNT")) {
4361 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4362 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4366 if (count > atoi (g_getenv ("LLVM_COUNT")))
4367 LLVM_FAILURE (ctx, "");
4372 sig = mono_method_signature (cfg->method);
4375 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4377 CHECK_FAILURE (ctx);
4380 linfo->rgctx_arg = TRUE;
4381 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4382 CHECK_FAILURE (ctx);
4385 * This maps parameter indexes in the original signature to the indexes in
4386 * the LLVM signature.
4388 ctx->pindexes = sinfo.pindexes;
4390 method = LLVMAddFunction (module, method_name, method_type);
4391 ctx->lmethod = method;
4393 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4394 LLVMSetLinkage (method, LLVMPrivateLinkage);
4396 LLVMAddFunctionAttr (method, LLVMUWTable);
4398 if (cfg->compile_aot) {
4399 LLVMSetLinkage (method, LLVMInternalLinkage);
4400 #if LLVM_API_VERSION == 0
4401 /* This causes an assertion in later LLVM versions */
4402 LLVMSetVisibility (method, LLVMHiddenVisibility);
4405 LLVMSetLinkage (method, LLVMPrivateLinkage);
4408 if (cfg->method->save_lmf)
4409 LLVM_FAILURE (ctx, "lmf");
4411 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4412 LLVM_FAILURE (ctx, "pinvoke signature");
4414 header = cfg->header;
4415 for (i = 0; i < header->num_clauses; ++i) {
4416 clause = &header->clauses [i];
4417 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4418 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4421 if (linfo->rgctx_arg) {
4422 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4424 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4425 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4426 * CC_X86_64_Mono in X86CallingConv.td.
4428 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4429 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4431 if (cfg->vret_addr) {
4432 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4433 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4436 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4437 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4440 names = g_new (char *, sig->param_count);
4441 mono_method_get_param_names (cfg->method, (const char **) names);
4443 for (i = 0; i < sig->param_count; ++i) {
4446 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4447 if (names [i] && names [i][0] != '\0')
4448 name = g_strdup_printf ("arg_%s", names [i]);
4450 name = g_strdup_printf ("arg_%d", i);
4451 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4453 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4454 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4459 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4460 max_block_num = MAX (max_block_num, bb->block_num);
4461 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4463 /* Add branches between non-consecutive bblocks */
4464 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4465 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4466 bb->next_bb != bb->last_ins->inst_false_bb) {
4468 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4469 inst->opcode = OP_BR;
4470 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4471 mono_bblock_add_inst (bb, inst);
4476 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4477 * was later optimized away, so clear these flags, and add them back for the still
4478 * present OP_LDADDR instructions.
4480 for (i = 0; i < cfg->next_vreg; ++i) {
4483 ins = get_vreg_to_inst (cfg, i);
4484 if (ins && ins != cfg->rgctx_var)
4485 ins->flags &= ~MONO_INST_INDIRECT;
4489 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4491 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4493 LLVMBuilderRef builder;
4495 char dname_buf[128];
4497 builder = create_builder (ctx);
4499 for (ins = bb->code; ins; ins = ins->next) {
4500 switch (ins->opcode) {
4505 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4507 CHECK_FAILURE (ctx);
4509 if (ins->opcode == OP_VPHI) {
4510 /* Treat valuetype PHI nodes as operating on the address itself */
4511 g_assert (ins->klass);
4512 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4516 * Have to precreate these, as they can be referenced by
4517 * earlier instructions.
4519 sprintf (dname_buf, "t%d", ins->dreg);
4521 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4523 if (ins->opcode == OP_VPHI)
4524 ctx->addresses [ins->dreg] = values [ins->dreg];
4526 g_ptr_array_add (phi_values, values [ins->dreg]);
4529 * Set the expected type of the incoming arguments since these have
4530 * to have the same type.
4532 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4533 int sreg1 = ins->inst_phi_args [i + 1];
4536 ctx->vreg_types [sreg1] = phi_type;
4541 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4550 * Create an ordering for bblocks, use the depth first order first, then
4551 * put the exception handling bblocks last.
4553 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4554 bb = cfg->bblocks [bb_index];
4555 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4556 g_ptr_array_add (bblock_list, bb);
4557 bblocks [bb->block_num].added = TRUE;
4561 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4562 if (!bblocks [bb->block_num].added)
4563 g_ptr_array_add (bblock_list, bb);
4567 * Second pass: generate code.
4569 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4570 bb = g_ptr_array_index (bblock_list, bb_index);
4572 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4575 process_bb (ctx, bb);
4576 CHECK_FAILURE (ctx);
4579 /* Add incoming phi values */
4580 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4581 GSList *l, *ins_list;
4583 ins_list = bblocks [bb->block_num].phi_nodes;
4585 for (l = ins_list; l; l = l->next) {
4586 PhiNode *node = l->data;
4587 MonoInst *phi = node->phi;
4588 int sreg1 = node->sreg;
4589 LLVMBasicBlockRef in_bb;
4594 in_bb = get_end_bb (ctx, node->in_bb);
4596 if (ctx->unreachable [node->in_bb->block_num])
4599 if (!values [sreg1])
4600 /* Can happen with values in EH clauses */
4601 LLVM_FAILURE (ctx, "incoming phi sreg1");
4603 if (phi->opcode == OP_VPHI) {
4604 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4605 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4607 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4609 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4610 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4611 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4616 /* Create the SWITCH statements for ENDFINALLY instructions */
4617 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4618 BBInfo *info = &bblocks [bb->block_num];
4620 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4621 LLVMValueRef switch_ins = l->data;
4622 GSList *bb_list = info->call_handler_return_bbs;
4624 for (i = 0; i < g_slist_length (bb_list); ++i)
4625 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4629 if (cfg->verbose_level > 1)
4630 mono_llvm_dump_value (method);
4632 if (cfg->compile_aot)
4633 mark_as_used (ctx->lmodule, method);
4635 if (cfg->compile_aot) {
4636 LLVMValueRef md_args [16];
4637 LLVMValueRef md_node;
4640 method_index = mono_aot_get_method_index (cfg->orig_method);
4641 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4642 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4643 md_node = LLVMMDNode (md_args, 2);
4644 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4645 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4648 if (cfg->compile_aot) {
4649 /* Don't generate native code, keep the LLVM IR */
4650 if (cfg->compile_aot && cfg->verbose_level)
4651 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4653 //LLVMVerifyFunction(method, 0);
4655 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
4657 if (cfg->verbose_level > 1)
4658 mono_llvm_dump_value (method);
4660 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
4662 /* Set by emit_cb */
4663 g_assert (cfg->code_len);
4665 /* FIXME: Free the LLVM IL for the function */
4673 /* Need to add unused phi nodes as they can be referenced by other values */
4674 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4675 LLVMBuilderRef builder;
4677 builder = create_builder (ctx);
4678 LLVMPositionBuilderAtEnd (builder, phi_bb);
4680 for (i = 0; i < phi_values->len; ++i) {
4681 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4682 if (LLVMGetInstructionParent (v) == NULL)
4683 LLVMInsertIntoBuilder (builder, v);
4686 LLVMDeleteFunction (method);
4691 g_free (ctx->addresses);
4692 g_free (ctx->vreg_types);
4693 g_free (ctx->vreg_cli_types);
4694 g_free (ctx->pindexes);
4695 g_free (ctx->is_dead);
4696 g_free (ctx->unreachable);
4697 g_ptr_array_free (phi_values, TRUE);
4698 g_free (ctx->bblocks);
4699 g_hash_table_destroy (ctx->region_to_handler);
4700 g_free (method_name);
4701 g_ptr_array_free (bblock_list, TRUE);
4703 for (l = ctx->builders; l; l = l->next) {
4704 LLVMBuilderRef builder = l->data;
4705 LLVMDisposeBuilder (builder);
4710 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4712 mono_loader_unlock ();
4716 * mono_llvm_emit_call:
4718 * Same as mono_arch_emit_call () for LLVM.
4721 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4724 MonoMethodSignature *sig;
4725 int i, n, stack_size;
4730 sig = call->signature;
4731 n = sig->param_count + sig->hasthis;
4733 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4735 if (cfg->disable_llvm)
4738 if (sig->call_convention == MONO_CALL_VARARG) {
4739 cfg->exception_message = g_strdup ("varargs");
4740 cfg->disable_llvm = TRUE;
4743 for (i = 0; i < n; ++i) {
4746 ainfo = call->cinfo->args + i;
4748 in = call->args [i];
4750 /* Simply remember the arguments */
4751 switch (ainfo->storage) {
4753 case LLVMArgInFPReg: {
4754 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4757 opcode = mono_type_to_regmove (cfg, t);
4758 if (opcode == OP_FMOVE) {
4759 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4760 ins->dreg = mono_alloc_freg (cfg);
4761 } else if (opcode == OP_LMOVE) {
4762 MONO_INST_NEW (cfg, ins, OP_LMOVE);
4763 ins->dreg = mono_alloc_lreg (cfg);
4765 MONO_INST_NEW (cfg, ins, OP_MOVE);
4766 ins->dreg = mono_alloc_ireg (cfg);
4768 ins->sreg1 = in->dreg;
4771 case LLVMArgVtypeByVal:
4772 case LLVMArgVtypeInReg:
4773 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4774 ins->dreg = mono_alloc_ireg (cfg);
4775 ins->sreg1 = in->dreg;
4776 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4779 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4780 cfg->exception_message = g_strdup ("ainfo->storage");
4781 cfg->disable_llvm = TRUE;
4785 if (!cfg->disable_llvm) {
4786 MONO_ADD_INS (cfg->cbb, ins);
4787 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4792 static unsigned char*
4793 alloc_cb (LLVMValueRef function, int size)
4797 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4801 return mono_domain_code_reserve (cfg->domain, size);
4803 return mono_domain_code_reserve (mono_domain_get (), size);
4808 emitted_cb (LLVMValueRef function, void *start, void *end)
4812 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4814 cfg->code_len = (guint8*)end - (guint8*)start;
4818 exception_cb (void *data)
4821 MonoJitExceptionInfo *ei;
4822 guint32 ei_len, i, j, nested_len, nindex;
4823 gpointer *type_info;
4824 int this_reg, this_offset;
4826 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4830 * data points to a DWARF FDE structure, convert it to our unwind format and
4832 * An alternative would be to save it directly, and modify our unwinder to work
4835 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);
4836 if (cfg->verbose_level > 1)
4837 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4839 /* Count nested clauses */
4841 for (i = 0; i < ei_len; ++i) {
4842 for (j = 0; j < ei_len; ++j) {
4843 gint32 cindex1 = *(gint32*)type_info [i];
4844 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4845 gint32 cindex2 = *(gint32*)type_info [j];
4846 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4848 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4854 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4855 cfg->llvm_ex_info_len = ei_len + nested_len;
4856 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4857 /* Fill the rest of the information from the type info */
4858 for (i = 0; i < ei_len; ++i) {
4859 gint32 clause_index = *(gint32*)type_info [i];
4860 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4862 cfg->llvm_ex_info [i].flags = clause->flags;
4863 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4867 * For nested clauses, the LLVM produced exception info associates the try interval with
4868 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4870 /* FIXME: These should be order with the normal clauses */
4872 for (i = 0; i < ei_len; ++i) {
4873 for (j = 0; j < ei_len; ++j) {
4874 gint32 cindex1 = *(gint32*)type_info [i];
4875 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4876 gint32 cindex2 = *(gint32*)type_info [j];
4877 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4879 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4881 * The try interval comes from the nested clause, everything else from the
4884 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4885 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4886 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4891 g_assert (nindex == ei_len + nested_len);
4892 cfg->llvm_this_reg = this_reg;
4893 cfg->llvm_this_offset = this_offset;
4895 /* type_info [i] is cfg mempool allocated, no need to free it */
4902 dlsym_cb (const char *name, void **symbol)
4908 if (!strcmp (name, "__bzero")) {
4909 *symbol = (void*)bzero;
4911 current = mono_dl_open (NULL, 0, NULL);
4914 err = mono_dl_symbol (current, name, symbol);
4916 mono_dl_close (current);
4918 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4919 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4925 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4927 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4931 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4933 LLVMTypeRef param_types [4];
4935 param_types [0] = param_type1;
4936 param_types [1] = param_type2;
4938 AddFunc (module, name, ret_type, param_types, 2);
4942 add_intrinsics (LLVMModuleRef module)
4944 /* Emit declarations of instrinsics */
4946 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4947 * type doesn't seem to do any locking.
4950 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4952 memset_param_count = 5;
4953 memset_func_name = "llvm.memset.p0i8.i32";
4955 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4959 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4961 memcpy_param_count = 5;
4962 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4964 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4968 LLVMTypeRef params [] = { LLVMDoubleType () };
4970 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4971 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4972 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4974 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4975 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4979 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4980 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4982 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4983 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4984 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4985 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4986 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4987 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4991 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4992 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4994 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4995 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4996 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4997 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4998 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4999 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5004 LLVMTypeRef arg_types [2];
5005 LLVMTypeRef ret_type;
5007 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5008 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5009 ret_type = LLVMInt32Type ();
5011 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5013 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5016 /* SSE intrinsics */
5017 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5019 LLVMTypeRef ret_type, arg_types [16];
5022 ret_type = type_to_simd_type (MONO_TYPE_I4);
5023 arg_types [0] = ret_type;
5024 arg_types [1] = ret_type;
5025 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5026 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5028 ret_type = type_to_simd_type (MONO_TYPE_I2);
5029 arg_types [0] = ret_type;
5030 arg_types [1] = ret_type;
5031 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5032 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5033 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5034 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5035 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5036 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5037 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5038 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5039 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5040 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5042 ret_type = type_to_simd_type (MONO_TYPE_I1);
5043 arg_types [0] = ret_type;
5044 arg_types [1] = ret_type;
5045 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5046 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5047 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5048 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5049 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5050 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5051 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5053 ret_type = type_to_simd_type (MONO_TYPE_R8);
5054 arg_types [0] = ret_type;
5055 arg_types [1] = ret_type;
5056 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5057 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5058 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5059 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5060 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5062 ret_type = type_to_simd_type (MONO_TYPE_R4);
5063 arg_types [0] = ret_type;
5064 arg_types [1] = ret_type;
5065 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5066 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5067 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5068 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5069 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5072 ret_type = type_to_simd_type (MONO_TYPE_I1);
5073 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5074 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5075 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5076 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5077 ret_type = type_to_simd_type (MONO_TYPE_I2);
5078 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5079 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5080 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5081 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5084 ret_type = type_to_simd_type (MONO_TYPE_R8);
5085 arg_types [0] = ret_type;
5086 arg_types [1] = ret_type;
5087 arg_types [2] = LLVMInt8Type ();
5088 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5089 ret_type = type_to_simd_type (MONO_TYPE_R4);
5090 arg_types [0] = ret_type;
5091 arg_types [1] = ret_type;
5092 arg_types [2] = LLVMInt8Type ();
5093 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5095 /* Conversion ops */
5096 ret_type = type_to_simd_type (MONO_TYPE_R8);
5097 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5098 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5099 ret_type = type_to_simd_type (MONO_TYPE_R4);
5100 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5101 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5102 ret_type = type_to_simd_type (MONO_TYPE_I4);
5103 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5104 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5105 ret_type = type_to_simd_type (MONO_TYPE_I4);
5106 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5107 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5108 ret_type = type_to_simd_type (MONO_TYPE_R4);
5109 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5110 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5111 ret_type = type_to_simd_type (MONO_TYPE_R8);
5112 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5113 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5115 ret_type = type_to_simd_type (MONO_TYPE_I4);
5116 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5117 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5118 ret_type = type_to_simd_type (MONO_TYPE_I4);
5119 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5120 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5123 ret_type = type_to_simd_type (MONO_TYPE_R8);
5124 arg_types [0] = ret_type;
5125 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5126 ret_type = type_to_simd_type (MONO_TYPE_R4);
5127 arg_types [0] = ret_type;
5128 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5129 ret_type = type_to_simd_type (MONO_TYPE_R4);
5130 arg_types [0] = ret_type;
5131 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5132 ret_type = type_to_simd_type (MONO_TYPE_R4);
5133 arg_types [0] = ret_type;
5134 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5137 ret_type = type_to_simd_type (MONO_TYPE_I2);
5138 arg_types [0] = ret_type;
5139 arg_types [1] = LLVMInt32Type ();
5140 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5141 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5142 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5143 ret_type = type_to_simd_type (MONO_TYPE_I4);
5144 arg_types [0] = ret_type;
5145 arg_types [1] = LLVMInt32Type ();
5146 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5147 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5148 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5149 ret_type = type_to_simd_type (MONO_TYPE_I8);
5150 arg_types [0] = ret_type;
5151 arg_types [1] = LLVMInt32Type ();
5152 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5153 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5156 ret_type = LLVMInt32Type ();
5157 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5158 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5161 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5164 /* Load/Store intrinsics */
5166 LLVMTypeRef arg_types [5];
5170 for (i = 1; i <= 8; i *= 2) {
5171 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5172 arg_types [1] = LLVMInt32Type ();
5173 arg_types [2] = LLVMInt1Type ();
5174 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5175 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5177 arg_types [0] = LLVMIntType (i * 8);
5178 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5179 arg_types [2] = LLVMInt32Type ();
5180 arg_types [3] = LLVMInt1Type ();
5181 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5182 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5188 add_types (MonoLLVMModule *lmodule)
5190 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5194 mono_llvm_init (void)
5196 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5200 init_jit_module (MonoDomain *domain)
5202 MonoJitICallInfo *info;
5203 MonoJitDomainInfo *dinfo;
5204 MonoLLVMModule *module;
5207 dinfo = domain_jit_info (domain);
5208 if (dinfo->llvm_module)
5211 mono_loader_lock ();
5213 if (dinfo->llvm_module) {
5214 mono_loader_unlock ();
5218 module = g_new0 (MonoLLVMModule, 1);
5220 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5221 module->module = LLVMModuleCreateWithName (name);
5223 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5225 add_intrinsics (module->module);
5228 module->llvm_types = g_hash_table_new (NULL, NULL);
5230 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5232 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5234 mono_memory_barrier ();
5236 dinfo->llvm_module = module;
5238 mono_loader_unlock ();
5242 mono_llvm_cleanup (void)
5244 if (aot_module.module)
5245 LLVMDisposeModule (aot_module.module);
5247 LLVMContextDispose (LLVMGetGlobalContext ());
5251 mono_llvm_free_domain_info (MonoDomain *domain)
5253 MonoJitDomainInfo *info = domain_jit_info (domain);
5254 MonoLLVMModule *module = info->llvm_module;
5260 if (module->llvm_types)
5261 g_hash_table_destroy (module->llvm_types);
5263 mono_llvm_dispose_ee (module->mono_ee);
5265 if (module->bb_names) {
5266 for (i = 0; i < module->bb_names_len; ++i)
5267 g_free (module->bb_names [i]);
5268 g_free (module->bb_names);
5270 //LLVMDisposeModule (module->module);
5274 info->llvm_module = NULL;
5278 mono_llvm_create_aot_module (const char *got_symbol)
5280 /* Delete previous module */
5281 if (aot_module.plt_entries)
5282 g_hash_table_destroy (aot_module.plt_entries);
5283 if (aot_module.module)
5284 LLVMDisposeModule (aot_module.module);
5286 memset (&aot_module, 0, sizeof (aot_module));
5288 aot_module.module = LLVMModuleCreateWithName ("aot");
5289 aot_module.got_symbol = got_symbol;
5291 add_intrinsics (aot_module.module);
5292 add_types (&aot_module);
5296 * We couldn't compute the type of the LLVM global representing the got because
5297 * its size is only known after all the methods have been emitted. So create
5298 * a dummy variable, and replace all uses it with the real got variable when
5299 * its size is known in mono_llvm_emit_aot_module ().
5302 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5304 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5305 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5308 /* Add a dummy personality function */
5310 LLVMBasicBlockRef lbb;
5311 LLVMBuilderRef lbuilder;
5312 LLVMValueRef personality;
5314 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5315 LLVMSetLinkage (personality, LLVMInternalLinkage);
5316 lbb = LLVMAppendBasicBlock (personality, "BB0");
5317 lbuilder = LLVMCreateBuilder ();
5318 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5319 LLVMBuildRetVoid (lbuilder);
5322 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5323 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5327 * Emit the aot module into the LLVM bitcode file FILENAME.
5330 mono_llvm_emit_aot_module (const char *filename, int got_size)
5332 LLVMTypeRef got_type;
5333 LLVMValueRef real_got;
5336 * Create the real got variable and replace all uses of the dummy variable with
5339 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5340 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5341 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5342 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5344 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5346 mark_as_used (&aot_module, real_got);
5348 /* Delete the dummy got so it doesn't become a global */
5349 LLVMDeleteGlobal (aot_module.got_var);
5351 emit_llvm_used (&aot_module);
5357 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5358 g_assert_not_reached ();
5363 LLVMWriteBitcodeToFile (aot_module.module, filename);
5368 - Emit LLVM IR from the mono IR using the LLVM C API.
5369 - The original arch specific code remains, so we can fall back to it if we run
5370 into something we can't handle.
5374 A partial list of issues:
5375 - Handling of opcodes which can throw exceptions.
5377 In the mono JIT, these are implemented using code like this:
5384 push throw_pos - method
5385 call <exception trampoline>
5387 The problematic part is push throw_pos - method, which cannot be represented
5388 in the LLVM IR, since it does not support label values.
5389 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5390 be implemented in JIT mode ?
5391 -> a possible but slower implementation would use the normal exception
5392 throwing code but it would need to control the placement of the throw code
5393 (it needs to be exactly after the compare+branch).
5394 -> perhaps add a PC offset intrinsics ?
5396 - efficient implementation of .ovf opcodes.
5398 These are currently implemented as:
5399 <ins which sets the condition codes>
5402 Some overflow opcodes are now supported by LLVM SVN.
5404 - exception handling, unwinding.
5405 - SSA is disabled for methods with exception handlers
5406 - How to obtain unwind info for LLVM compiled methods ?
5407 -> this is now solved by converting the unwind info generated by LLVM
5409 - LLVM uses the c++ exception handling framework, while we use our home grown
5410 code, and couldn't use the c++ one:
5411 - its not supported under VC++, other exotic platforms.
5412 - it might be impossible to support filter clauses with it.
5416 The trampolines need a predictable call sequence, since they need to disasm
5417 the calling code to obtain register numbers / offsets.
5419 LLVM currently generates this code in non-JIT mode:
5420 mov -0x98(%rax),%eax
5422 Here, the vtable pointer is lost.
5423 -> solution: use one vtable trampoline per class.
5425 - passing/receiving the IMT pointer/RGCTX.
5426 -> solution: pass them as normal arguments ?
5430 LLVM does not allow the specification of argument registers etc. This means
5431 that all calls are made according to the platform ABI.
5433 - passing/receiving vtypes.
5435 Vtypes passed/received in registers are handled by the front end by using
5436 a signature with scalar arguments, and loading the parts of the vtype into those
5439 Vtypes passed on the stack are handled using the 'byval' attribute.
5443 Supported though alloca, we need to emit the load/store code.
5447 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5448 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5449 This is made easier because the IR is already in SSA form.
5450 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5451 types are frequently used incorrectly.
5456 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5457 append the AOT data structures to that file. For methods which cannot be
5458 handled by LLVM, the normal JIT compiled versions are used.
5461 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5462 * - each bblock should end with a branch
5463 * - setting the return value, making cfg->ret non-volatile
5464 * - avoid some transformations in the JIT which make it harder for us to generate
5466 * - use pointer types to help optimizations.