2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
10 #include <mono/utils/mono-tls.h>
12 #ifndef __STDC_LIMIT_MACROS
13 #define __STDC_LIMIT_MACROS
15 #ifndef __STDC_CONSTANT_MACROS
16 #define __STDC_CONSTANT_MACROS
19 #include "llvm-c/Core.h"
20 #include "llvm-c/ExecutionEngine.h"
21 #include "llvm-c/BitWriter.h"
22 #include "llvm-c/Analysis.h"
24 #include "mini-llvm-cpp.h"
27 * Information associated by mono with LLVM modules.
31 LLVMValueRef
throw, rethrow
, throw_corlib_exception
;
32 GHashTable
*llvm_types
;
34 const char *got_symbol
;
35 GHashTable
*plt_entries
;
39 * Information associated by the backend with mono basic blocks.
42 LLVMBasicBlockRef bblock
, end_bblock
;
43 LLVMValueRef finally_ind
;
44 gboolean added
, invoke_target
;
46 * If this bblock is the start of a finally clause, this is a list of bblocks it
47 * needs to branch to in ENDFINALLY.
49 GSList
*call_handler_return_bbs
;
51 * If this bblock is the start of a finally clause, this is the bblock that
52 * CALL_HANDLER needs to branch to.
54 LLVMBasicBlockRef call_handler_target_bb
;
55 /* The list of switch statements generated by ENDFINALLY instructions */
56 GSList
*endfinally_switch_ins_list
;
61 * Structure containing emit state
66 /* Maps method names to the corresponding LLVMValueRef */
67 GHashTable
*emitted_method_decls
;
71 MonoLLVMModule
*lmodule
;
74 int sindex
, default_index
, ex_index
;
75 LLVMBuilderRef builder
;
76 LLVMValueRef
*values
, *addresses
;
77 MonoType
**vreg_cli_types
;
79 MonoMethodSignature
*sig
;
81 GHashTable
*region_to_handler
;
82 LLVMBuilderRef alloca_builder
;
83 LLVMValueRef last_alloca
;
84 LLVMValueRef rgctx_arg
;
85 LLVMTypeRef
*vreg_types
;
87 gboolean
*unreachable
;
96 MonoBasicBlock
*in_bb
;
101 * Instruction metadata
102 * This is the same as ins_info, but LREG != IREG.
110 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
111 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
118 /* keep in sync with the enum in mini.h */
121 #include "mini-ops.h"
126 #if SIZEOF_VOID_P == 4
127 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
129 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
132 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
135 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
137 #define TRACE_FAILURE(msg)
141 #define IS_TARGET_X86 1
143 #define IS_TARGET_X86 0
146 #define LLVM_FAILURE(ctx, reason) do { \
147 TRACE_FAILURE (reason); \
148 (ctx)->cfg->exception_message = g_strdup (reason); \
149 (ctx)->cfg->disable_llvm = TRUE; \
153 #define CHECK_FAILURE(ctx) do { \
154 if ((ctx)->cfg->disable_llvm) \
158 static LLVMIntPredicate cond_to_llvm_cond
[] = {
171 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
184 static LLVMExecutionEngineRef ee
;
185 static MonoNativeTlsKey current_cfg_tls_id
;
187 static MonoLLVMModule jit_module
, aot_module
;
188 static gboolean jit_module_inited
;
189 static int memset_param_count
, memcpy_param_count
;
190 static const char *memset_func_name
;
191 static const char *memcpy_func_name
;
192 static const char *eh_selector_name
;
194 static void init_jit_module (void);
199 * The LLVM type with width == sizeof (gpointer)
204 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
210 * Return the size of the LLVM representation of the vtype T.
213 get_vtype_size (MonoType
*t
)
217 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
219 while (size
< sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
226 * simd_class_to_llvm_type:
228 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
231 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
233 if (!strcmp (klass
->name
, "Vector2d")) {
234 return LLVMVectorType (LLVMDoubleType (), 2);
235 } else if (!strcmp (klass
->name
, "Vector2l")) {
236 return LLVMVectorType (LLVMInt64Type (), 2);
237 } else if (!strcmp (klass
->name
, "Vector2ul")) {
238 return LLVMVectorType (LLVMInt64Type (), 2);
239 } else if (!strcmp (klass
->name
, "Vector4i")) {
240 return LLVMVectorType (LLVMInt32Type (), 4);
241 } else if (!strcmp (klass
->name
, "Vector4ui")) {
242 return LLVMVectorType (LLVMInt32Type (), 4);
243 } else if (!strcmp (klass
->name
, "Vector4f")) {
244 return LLVMVectorType (LLVMFloatType (), 4);
245 } else if (!strcmp (klass
->name
, "Vector8s")) {
246 return LLVMVectorType (LLVMInt16Type (), 8);
247 } else if (!strcmp (klass
->name
, "Vector8us")) {
248 return LLVMVectorType (LLVMInt16Type (), 8);
249 } else if (!strcmp (klass
->name
, "Vector16sb")) {
250 return LLVMVectorType (LLVMInt8Type (), 16);
251 } else if (!strcmp (klass
->name
, "Vector16b")) {
252 return LLVMVectorType (LLVMInt8Type (), 16);
254 printf ("%s\n", klass
->name
);
260 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
261 static inline G_GNUC_UNUSED LLVMTypeRef
262 type_to_simd_type (int type
)
266 return LLVMVectorType (LLVMInt8Type (), 16);
268 return LLVMVectorType (LLVMInt16Type (), 8);
270 return LLVMVectorType (LLVMInt32Type (), 4);
272 return LLVMVectorType (LLVMInt64Type (), 2);
274 return LLVMVectorType (LLVMDoubleType (), 2);
276 return LLVMVectorType (LLVMFloatType (), 4);
278 g_assert_not_reached ();
286 * Return the LLVM type corresponding to T.
289 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
292 return LLVMPointerType (LLVMInt8Type (), 0);
295 return LLVMVoidType ();
297 return LLVMInt8Type ();
299 return LLVMInt16Type ();
301 return LLVMInt32Type ();
303 return LLVMInt8Type ();
305 return LLVMInt16Type ();
307 return LLVMInt32Type ();
308 case MONO_TYPE_BOOLEAN
:
309 return LLVMInt8Type ();
312 return LLVMInt64Type ();
314 return LLVMInt16Type ();
316 return LLVMFloatType ();
318 return LLVMDoubleType ();
321 return IntPtrType ();
322 case MONO_TYPE_OBJECT
:
323 case MONO_TYPE_CLASS
:
324 case MONO_TYPE_ARRAY
:
325 case MONO_TYPE_SZARRAY
:
326 case MONO_TYPE_STRING
:
328 return LLVMPointerType (IntPtrType (), 0);
331 /* Because of generic sharing */
332 return IntPtrType ();
333 case MONO_TYPE_GENERICINST
:
334 if (!mono_type_generic_inst_is_valuetype (t
))
335 return IntPtrType ();
337 case MONO_TYPE_VALUETYPE
:
338 case MONO_TYPE_TYPEDBYREF
: {
342 klass
= mono_class_from_mono_type (t
);
344 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
345 return simd_class_to_llvm_type (ctx
, klass
);
348 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
349 ltype
= g_hash_table_lookup (ctx
->lmodule
->llvm_types
, klass
);
352 LLVMTypeRef
*eltypes
;
354 size
= get_vtype_size (t
);
356 eltypes
= g_new (LLVMTypeRef
, size
);
357 for (i
= 0; i
< size
; ++i
)
358 eltypes
[i
] = LLVMInt8Type ();
360 /* We couldn't name these types since LLVM uses structural type equality */
361 ltype
= LLVMStructType (eltypes
, size
, FALSE
);
362 g_hash_table_insert (ctx
->lmodule
->llvm_types
, klass
, ltype
);
369 printf ("X: %d\n", t
->type
);
370 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
371 ctx
->cfg
->disable_llvm
= TRUE
;
379 * Return whenever T is an unsigned int type.
382 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
398 * type_to_llvm_arg_type:
400 * Same as type_to_llvm_type, but treat i8/i16 as i32.
403 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
405 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
407 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
409 * LLVM generates code which only sets the lower bits, while JITted
410 * code expects all the bits to be set.
412 ptype
= LLVMInt32Type ();
419 * llvm_type_to_stack_type:
421 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
424 static G_GNUC_UNUSED LLVMTypeRef
425 llvm_type_to_stack_type (LLVMTypeRef type
)
429 if (type
== LLVMInt8Type ())
430 return LLVMInt32Type ();
431 else if (type
== LLVMInt16Type ())
432 return LLVMInt32Type ();
433 else if (type
== LLVMFloatType ())
434 return LLVMDoubleType ();
440 * regtype_to_llvm_type:
442 * Return the LLVM type corresponding to the regtype C used in instruction
446 regtype_to_llvm_type (char c
)
450 return LLVMInt32Type ();
452 return LLVMInt64Type ();
454 return LLVMDoubleType ();
463 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
466 op_to_llvm_type (int opcode
)
471 return LLVMInt8Type ();
474 return LLVMInt8Type ();
477 return LLVMInt16Type ();
480 return LLVMInt16Type ();
483 return LLVMInt32Type ();
486 return LLVMInt32Type ();
488 return LLVMInt64Type ();
490 return LLVMFloatType ();
492 return LLVMDoubleType ();
494 return LLVMInt64Type ();
496 return LLVMInt32Type ();
498 return LLVMInt64Type ();
501 return LLVMInt8Type ();
504 return LLVMInt16Type ();
507 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
514 return LLVMInt32Type ();
521 return LLVMInt64Type ();
523 printf ("%s\n", mono_inst_name (opcode
));
524 g_assert_not_reached ();
530 * load_store_to_llvm_type:
532 * Return the size/sign/zero extension corresponding to the load/store opcode
536 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
542 case OP_LOADI1_MEMBASE
:
543 case OP_STOREI1_MEMBASE_REG
:
544 case OP_STOREI1_MEMBASE_IMM
:
547 return LLVMInt8Type ();
548 case OP_LOADU1_MEMBASE
:
552 return LLVMInt8Type ();
553 case OP_LOADI2_MEMBASE
:
554 case OP_STOREI2_MEMBASE_REG
:
555 case OP_STOREI2_MEMBASE_IMM
:
558 return LLVMInt16Type ();
559 case OP_LOADU2_MEMBASE
:
563 return LLVMInt16Type ();
564 case OP_LOADI4_MEMBASE
:
565 case OP_LOADU4_MEMBASE
:
568 case OP_STOREI4_MEMBASE_REG
:
569 case OP_STOREI4_MEMBASE_IMM
:
571 return LLVMInt32Type ();
572 case OP_LOADI8_MEMBASE
:
574 case OP_STOREI8_MEMBASE_REG
:
575 case OP_STOREI8_MEMBASE_IMM
:
577 return LLVMInt64Type ();
578 case OP_LOADR4_MEMBASE
:
579 case OP_STORER4_MEMBASE_REG
:
581 return LLVMFloatType ();
582 case OP_LOADR8_MEMBASE
:
583 case OP_STORER8_MEMBASE_REG
:
585 return LLVMDoubleType ();
586 case OP_LOAD_MEMBASE
:
588 case OP_STORE_MEMBASE_REG
:
589 case OP_STORE_MEMBASE_IMM
:
590 *size
= sizeof (gpointer
);
591 return IntPtrType ();
593 g_assert_not_reached ();
601 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
604 ovf_op_to_intrins (int opcode
)
608 return "llvm.sadd.with.overflow.i32";
610 return "llvm.uadd.with.overflow.i32";
612 return "llvm.ssub.with.overflow.i32";
614 return "llvm.usub.with.overflow.i32";
616 return "llvm.smul.with.overflow.i32";
618 return "llvm.umul.with.overflow.i32";
620 return "llvm.sadd.with.overflow.i64";
622 return "llvm.uadd.with.overflow.i64";
624 return "llvm.ssub.with.overflow.i64";
626 return "llvm.usub.with.overflow.i64";
628 return "llvm.smul.with.overflow.i64";
630 return "llvm.umul.with.overflow.i64";
632 g_assert_not_reached ();
638 simd_op_to_intrins (int opcode
)
641 #if defined(TARGET_X86) || defined(TARGET_AMD64)
643 return "llvm.x86.sse2.min.pd";
645 return "llvm.x86.sse.min.ps";
647 return "llvm.x86.sse41.pminud";
649 return "llvm.x86.sse41.pminuw";
651 return "llvm.x86.sse2.pminu.b";
653 return "llvm.x86.sse2.pmins.w";
655 return "llvm.x86.sse2.max.pd";
657 return "llvm.x86.sse.max.ps";
659 return "llvm.x86.sse3.hadd.pd";
661 return "llvm.x86.sse3.hadd.ps";
663 return "llvm.x86.sse3.hsub.pd";
665 return "llvm.x86.sse3.hsub.ps";
667 return "llvm.x86.sse41.pmaxud";
669 return "llvm.x86.sse41.pmaxuw";
671 return "llvm.x86.sse2.pmaxu.b";
673 return "llvm.x86.sse3.addsub.ps";
675 return "llvm.x86.sse3.addsub.pd";
676 case OP_EXTRACT_MASK
:
677 return "llvm.x86.sse2.pmovmskb.128";
680 return "llvm.x86.sse2.psrli.w";
683 return "llvm.x86.sse2.psrli.d";
686 return "llvm.x86.sse2.psrli.q";
689 return "llvm.x86.sse2.pslli.w";
692 return "llvm.x86.sse2.pslli.d";
695 return "llvm.x86.sse2.pslli.q";
698 return "llvm.x86.sse2.psrai.w";
701 return "llvm.x86.sse2.psrai.d";
703 return "llvm.x86.sse2.padds.b";
705 return "llvm.x86.sse2.padds.w";
707 return "llvm.x86.sse2.psubs.b";
709 return "llvm.x86.sse2.psubs.w";
710 case OP_PADDB_SAT_UN
:
711 return "llvm.x86.sse2.paddus.b";
712 case OP_PADDW_SAT_UN
:
713 return "llvm.x86.sse2.paddus.w";
714 case OP_PSUBB_SAT_UN
:
715 return "llvm.x86.sse2.psubus.b";
716 case OP_PSUBW_SAT_UN
:
717 return "llvm.x86.sse2.psubus.w";
719 return "llvm.x86.sse2.pavg.b";
721 return "llvm.x86.sse2.pavg.w";
723 return "llvm.x86.sse.sqrt.ps";
725 return "llvm.x86.sse2.sqrt.pd";
727 return "llvm.x86.sse.rsqrt.ps";
729 return "llvm.x86.sse.rcp.ps";
731 return "llvm.x86.sse2.pcmpeq.b";
733 return "llvm.x86.sse2.pcmpeq.w";
735 return "llvm.x86.sse2.pcmpeq.d";
737 return "llvm.x86.sse41.pcmpeqq";
739 return "llvm.x86.sse2.pcmpgt.b";
741 return "llvm.x86.sse2.cvtdq2pd";
743 return "llvm.x86.sse2.cvtdq2ps";
745 return "llvm.x86.sse2.cvtpd2dq";
747 return "llvm.x86.sse2.cvtps2dq";
749 return "llvm.x86.sse2.cvtpd2ps";
751 return "llvm.x86.sse2.cvtps2pd";
753 return "llvm.x86.sse2.cvttpd2dq";
755 return "llvm.x86.sse2.cvttps2dq";
757 return "llvm.x86.sse.cmp.ps";
759 return "llvm.x86.sse2.cmp.pd";
761 return "llvm.x86.sse2.packsswb.128";
763 return "llvm.x86.sse2.packssdw.128";
765 return "llvm.x86.sse2.packuswb.128";
767 return "llvm.x86.sse41.packusdw";
769 return "llvm.x86.sse2.pmulh.w";
770 case OP_PMULW_HIGH_UN
:
771 return "llvm.x86.sse2.pmulhu.w";
774 g_assert_not_reached ();
780 simd_op_to_llvm_type (int opcode
)
782 #if defined(TARGET_X86) || defined(TARGET_AMD64)
786 return type_to_simd_type (MONO_TYPE_R8
);
789 return type_to_simd_type (MONO_TYPE_I8
);
792 return type_to_simd_type (MONO_TYPE_I4
);
797 return type_to_simd_type (MONO_TYPE_I2
);
801 return type_to_simd_type (MONO_TYPE_I1
);
803 return type_to_simd_type (MONO_TYPE_R4
);
806 return type_to_simd_type (MONO_TYPE_I4
);
810 return type_to_simd_type (MONO_TYPE_R8
);
814 return type_to_simd_type (MONO_TYPE_R4
);
815 case OP_EXTRACT_MASK
:
816 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_R8
);
827 g_assert_not_reached ();
838 * Return the LLVM basic block corresponding to BB.
840 static LLVMBasicBlockRef
841 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
845 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
846 sprintf (bb_name
, "BB%d", bb
->block_num
);
848 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
849 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
852 return ctx
->bblocks
[bb
->block_num
].bblock
;
858 * Return the last LLVM bblock corresponding to BB.
859 * This might not be equal to the bb returned by get_bb () since we need to generate
860 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
862 static LLVMBasicBlockRef
863 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
866 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
869 static LLVMBasicBlockRef
870 gen_bb (EmitContext
*ctx
, const char *prefix
)
874 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
875 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
881 * Return the target of the patch identified by TYPE and TARGET.
884 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
888 memset (&ji
, 0, sizeof (ji
));
890 ji
.data
.target
= target
;
892 return mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
);
898 * Emit code to convert the LLVM value V to DTYPE.
901 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
903 LLVMTypeRef stype
= LLVMTypeOf (v
);
905 if (stype
!= dtype
) {
906 gboolean ext
= FALSE
;
909 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
911 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
913 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
917 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
919 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
920 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
923 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
924 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
925 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
926 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
927 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
928 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
929 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
930 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
932 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
933 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
934 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
935 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
936 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
937 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
939 #ifdef MONO_ARCH_SOFT_FLOAT
940 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
941 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
942 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
943 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
946 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
947 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
950 LLVMDumpValue (LLVMConstNull (dtype
));
951 g_assert_not_reached ();
959 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
961 return convert_full (ctx
, v
, dtype
, FALSE
);
965 * emit_volatile_load:
967 * If vreg is volatile, emit a load from its address.
970 emit_volatile_load (EmitContext
*ctx
, int vreg
)
974 LLVMValueRef v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
975 t
= ctx
->vreg_cli_types
[vreg
];
976 if (t
&& !t
->byref
) {
978 * Might have to zero extend since llvm doesn't have
981 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
982 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
983 else if (t
->type
== MONO_TYPE_U8
)
984 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
991 * emit_volatile_store:
993 * If VREG is volatile, emit a store from its value to its address.
996 emit_volatile_store (EmitContext
*ctx
, int vreg
)
998 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1000 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1001 g_assert (ctx
->addresses
[vreg
]);
1002 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1008 * Maps parameter indexes in the original signature to parameter indexes
1009 * in the LLVM signature.
1012 /* The indexes of various special arguments in the LLVM signature */
1013 int vret_arg_pindex
, this_arg_pindex
, rgctx_arg_pindex
, imt_arg_pindex
;
1017 * sig_to_llvm_sig_full:
1019 * Return the LLVM signature corresponding to the mono signature SIG using the
1020 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1023 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
,
1026 LLVMTypeRef ret_type
;
1027 LLVMTypeRef
*param_types
= NULL
;
1029 int i
, j
, pindex
, vret_arg_pindex
= 0;
1031 gboolean vretaddr
= FALSE
;
1034 memset (sinfo
, 0, sizeof (LLVMSigInfo
));
1036 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1037 CHECK_FAILURE (ctx
);
1039 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
1040 /* LLVM models this by returning an aggregate value */
1041 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1042 LLVMTypeRef members
[2];
1044 members
[0] = IntPtrType ();
1045 ret_type
= LLVMStructType (members
, 1, FALSE
);
1047 g_assert_not_reached ();
1049 } else if (cinfo
&& MONO_TYPE_ISSTRUCT (sig
->ret
)) {
1050 g_assert (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
);
1052 ret_type
= LLVMVoidType ();
1055 pindexes
= g_new0 (int, sig
->param_count
);
1056 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 2) + 3);
1058 if (cinfo
&& cinfo
->rgctx_arg
) {
1060 sinfo
->rgctx_arg_pindex
= pindex
;
1061 param_types
[pindex
] = IntPtrType ();
1064 if (cinfo
&& cinfo
->imt_arg
&& IS_LLVM_MONO_BRANCH
) {
1066 sinfo
->imt_arg_pindex
= pindex
;
1067 param_types
[pindex
] = IntPtrType ();
1071 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1072 vret_arg_pindex
= pindex
;
1073 if (cinfo
->vret_arg_index
== 1) {
1074 /* Add the slots consumed by the first argument */
1075 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1076 switch (ainfo
->storage
) {
1077 case LLVMArgVtypeInReg
:
1078 for (j
= 0; j
< 2; ++j
) {
1079 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1089 sinfo
->vret_arg_pindex
= vret_arg_pindex
;
1092 if (vretaddr
&& vret_arg_pindex
== pindex
)
1093 param_types
[pindex
++] = IntPtrType ();
1096 sinfo
->this_arg_pindex
= pindex
;
1097 param_types
[pindex
++] = IntPtrType ();
1099 if (vretaddr
&& vret_arg_pindex
== pindex
)
1100 param_types
[pindex
++] = IntPtrType ();
1101 for (i
= 0; i
< sig
->param_count
; ++i
) {
1102 if (vretaddr
&& vret_arg_pindex
== pindex
)
1103 param_types
[pindex
++] = IntPtrType ();
1104 pindexes
[i
] = pindex
;
1105 if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeInReg
) {
1106 for (j
= 0; j
< 2; ++j
) {
1107 switch (cinfo
->args
[i
+ sig
->hasthis
].pair_storage
[j
]) {
1109 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
1114 g_assert_not_reached ();
1117 } else if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
) {
1118 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1119 CHECK_FAILURE (ctx
);
1120 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1123 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1126 if (vretaddr
&& vret_arg_pindex
== pindex
)
1127 param_types
[pindex
++] = IntPtrType ();
1129 CHECK_FAILURE (ctx
);
1131 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1132 g_free (param_types
);
1135 sinfo
->pindexes
= pindexes
;
1143 g_free (param_types
);
1149 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1151 return sig_to_llvm_sig_full (ctx
, sig
, NULL
, NULL
);
1155 * LLVMFunctionType1:
1157 * Create an LLVM function type from the arguments.
1159 static G_GNUC_UNUSED LLVMTypeRef
1160 LLVMFunctionType1(LLVMTypeRef ReturnType
,
1161 LLVMTypeRef ParamType1
,
1164 LLVMTypeRef param_types
[1];
1166 param_types
[0] = ParamType1
;
1168 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1172 * LLVMFunctionType2:
1174 * Create an LLVM function type from the arguments.
1177 LLVMFunctionType2(LLVMTypeRef ReturnType
,
1178 LLVMTypeRef ParamType1
,
1179 LLVMTypeRef ParamType2
,
1182 LLVMTypeRef param_types
[2];
1184 param_types
[0] = ParamType1
;
1185 param_types
[1] = ParamType2
;
1187 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1191 * LLVMFunctionType3:
1193 * Create an LLVM function type from the arguments.
1196 LLVMFunctionType3(LLVMTypeRef ReturnType
,
1197 LLVMTypeRef ParamType1
,
1198 LLVMTypeRef ParamType2
,
1199 LLVMTypeRef ParamType3
,
1202 LLVMTypeRef param_types
[3];
1204 param_types
[0] = ParamType1
;
1205 param_types
[1] = ParamType2
;
1206 param_types
[2] = ParamType3
;
1208 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1214 * Create an LLVM builder and remember it so it can be freed later.
1216 static LLVMBuilderRef
1217 create_builder (EmitContext
*ctx
)
1219 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1221 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1227 get_plt_entry (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1229 char *callee_name
= mono_aot_get_plt_symbol (type
, data
);
1230 LLVMValueRef callee
;
1235 if (ctx
->cfg
->compile_aot
)
1236 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1237 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1240 callee
= g_hash_table_lookup (ctx
->lmodule
->plt_entries
, callee_name
);
1242 callee
= LLVMAddFunction (ctx
->module
, callee_name
, llvm_sig
);
1244 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1246 g_hash_table_insert (ctx
->lmodule
->plt_entries
, (char*)callee_name
, callee
);
1253 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1255 MonoMethodHeader
*header
= cfg
->header
;
1256 MonoExceptionClause
*clause
;
1260 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1261 return (bb
->region
>> 8) - 1;
1264 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1265 clause
= &header
->clauses
[i
];
1267 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1275 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1277 LLVMValueRef md_arg
;
1280 if (!IS_LLVM_MONO_BRANCH
)
1283 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1284 md_arg
= LLVMMDString ("mono", 4);
1285 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1291 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1295 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1297 MonoCompile
*cfg
= ctx
->cfg
;
1299 LLVMBuilderRef builder
= *builder_ref
;
1302 clause_index
= get_handler_clause (cfg
, bb
);
1304 if (clause_index
!= -1) {
1305 MonoMethodHeader
*header
= cfg
->header
;
1306 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1307 MonoBasicBlock
*tblock
;
1308 LLVMBasicBlockRef ex_bb
, noex_bb
;
1311 * Have to use an invoke instead of a call, branching to the
1312 * handler bblock of the clause containing this bblock.
1315 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1317 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1320 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1322 ex_bb
= get_bb (ctx
, tblock
);
1324 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1327 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1329 builder
= ctx
->builder
= create_builder (ctx
);
1330 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1332 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1334 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1335 ctx
->builder
= builder
;
1338 *builder_ref
= ctx
->builder
;
1344 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
1346 const char *intrins_name
;
1347 LLVMValueRef args
[16], res
;
1348 LLVMTypeRef addr_type
;
1350 if (is_faulting
&& bb
->region
!= -1 && IS_LLVM_MONO_BRANCH
) {
1352 * We handle loads which can fault by calling a mono specific intrinsic
1353 * using an invoke, so they are handled properly inside try blocks.
1354 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1355 * are marked with IntrReadArgMem.
1359 intrins_name
= "llvm.mono.load.i8.p0i8";
1362 intrins_name
= "llvm.mono.load.i16.p0i16";
1365 intrins_name
= "llvm.mono.load.i32.p0i32";
1368 intrins_name
= "llvm.mono.load.i64.p0i64";
1371 g_assert_not_reached ();
1374 addr_type
= LLVMTypeOf (addr
);
1375 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1376 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1379 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1380 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1381 res
= emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 3);
1383 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1384 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1385 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1386 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1393 * We emit volatile loads for loads which can fault, because otherwise
1394 * LLVM will generate invalid code when encountering a load from a
1397 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1399 /* Mark it with a custom metadata */
1402 set_metadata_flag (res, "mono.faulting.load");
1410 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, gboolean is_faulting
)
1412 const char *intrins_name
;
1413 LLVMValueRef args
[16];
1415 if (is_faulting
&& bb
->region
!= -1 && IS_LLVM_MONO_BRANCH
) {
1418 intrins_name
= "llvm.mono.store.i8.p0i8";
1421 intrins_name
= "llvm.mono.store.i16.p0i16";
1424 intrins_name
= "llvm.mono.store.i32.p0i32";
1427 intrins_name
= "llvm.mono.store.i64.p0i64";
1430 g_assert_not_reached ();
1433 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
1434 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
1435 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1440 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1441 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1442 emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 4);
1444 LLVMBuildStore (*builder_ref
, value
, addr
);
1449 * emit_cond_system_exception:
1451 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1452 * Might set the ctx exception.
1455 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
1457 LLVMBasicBlockRef ex_bb
, noex_bb
;
1458 LLVMBuilderRef builder
;
1459 MonoClass
*exc_class
;
1460 LLVMValueRef args
[2];
1462 ex_bb
= gen_bb (ctx
, "EX_BB");
1463 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1465 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
1467 exc_class
= mono_class_from_name (mono_get_corlib (), "System", exc_type
);
1468 g_assert (exc_class
);
1470 /* Emit exception throwing code */
1471 builder
= create_builder (ctx
);
1472 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
1474 if (!ctx
->lmodule
->throw_corlib_exception
) {
1475 LLVMValueRef callee
;
1477 const char *icall_name
;
1479 MonoMethodSignature
*throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 2);
1480 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
1481 throw_sig
->params
[0] = &mono_get_int32_class ()->byval_arg
;
1482 if (IS_LLVM_MONO_BRANCH
) {
1483 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
1484 throw_sig
->params
[1] = &mono_get_intptr_class ()->byval_arg
;
1486 icall_name
= "llvm_throw_corlib_exception_trampoline";
1487 throw_sig
->params
[1] = &mono_get_int32_class ()->byval_arg
;
1489 sig
= sig_to_llvm_sig (ctx
, throw_sig
);
1491 if (ctx
->cfg
->compile_aot
) {
1492 callee
= get_plt_entry (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
1494 callee
= LLVMAddFunction (ctx
->module
, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx
, throw_sig
));
1497 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1498 * - On x86, LLVM generated code doesn't push the arguments
1499 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1500 * arguments, not a pc offset.
1502 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
1505 mono_memory_barrier ();
1506 ctx
->lmodule
->throw_corlib_exception
= callee
;
1510 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
1512 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
, FALSE
);
1514 if (IS_LLVM_MONO_BRANCH
) {
1516 * The LLVM mono branch contains changes so a block address can be passed as an
1517 * argument to a call.
1519 args
[1] = LLVMBuildPtrToInt (builder
, LLVMBlockAddress (ctx
->lmethod
, ex_bb
), IntPtrType (), "");
1520 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1523 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1524 * otherwise only the line numbers in stack traces are incorrect.
1526 if (bb
->region
!= -1 && !IS_LLVM_MONO_BRANCH
)
1527 LLVM_FAILURE (ctx
, "system-ex-in-region");
1529 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1530 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1533 LLVMBuildUnreachable (builder
);
1535 ctx
->builder
= create_builder (ctx
);
1536 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1538 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1548 * emit_reg_to_vtype:
1550 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1553 emit_reg_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
)
1557 size
= get_vtype_size (t
);
1559 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1560 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1563 for (j
= 0; j
< 2; ++j
) {
1564 LLVMValueRef index
[2], addr
;
1565 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1566 LLVMTypeRef part_type
;
1568 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1571 part_type
= LLVMIntType (part_size
* 8);
1572 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1573 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1574 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1576 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1577 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1578 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1580 switch (ainfo
->pair_storage
[j
]) {
1582 LLVMBuildStore (builder
, convert (ctx
, regs
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
1587 g_assert_not_reached ();
1590 size
-= sizeof (gpointer
);
1595 * emit_vtype_to_reg:
1597 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1598 * into REGS, and the number of registers into NREGS.
1601 emit_vtype_to_reg (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
, guint32
*nregs
)
1606 size
= get_vtype_size (t
);
1608 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1609 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1612 for (j
= 0; j
< 2; ++j
) {
1613 LLVMValueRef index
[2], addr
;
1614 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1616 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1619 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1620 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1621 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1623 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1624 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1625 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1627 switch (ainfo
->pair_storage
[j
]) {
1629 regs
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
1634 g_assert_not_reached ();
1636 size
-= sizeof (gpointer
);
1643 build_alloca (EmitContext
*ctx
, MonoType
*t
)
1645 MonoClass
*k
= mono_class_from_mono_type (t
);
1648 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
1651 align
= mono_class_min_align (k
);
1653 /* Sometimes align is not a power of 2 */
1654 while (mono_is_power_of_two (align
) == -1)
1658 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1659 * get executed every time control reaches them.
1661 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
1663 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, type_to_llvm_type (ctx
, t
), NULL
, align
, "");
1664 return ctx
->last_alloca
;
1668 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1671 mark_as_used (LLVMModuleRef module
, LLVMValueRef global
)
1673 LLVMTypeRef used_type
;
1674 LLVMValueRef used
, used_elem
;
1676 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1677 used
= LLVMAddGlobal (module
, used_type
, "llvm.used");
1678 used_elem
= LLVMConstBitCast (global
, LLVMPointerType (LLVMInt8Type (), 0));
1679 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem
, 1));
1680 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
1681 LLVMSetSection (used
, "llvm.metadata");
1687 * Emit code to load/convert arguments.
1690 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
1693 MonoCompile
*cfg
= ctx
->cfg
;
1694 MonoMethodSignature
*sig
= ctx
->sig
;
1695 LLVMCallInfo
*linfo
= ctx
->linfo
;
1698 ctx
->alloca_builder
= create_builder (ctx
);
1701 * Handle indirect/volatile variables by allocating memory for them
1702 * using 'alloca', and storing their address in a temporary.
1704 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
1705 MonoInst
*var
= cfg
->varinfo
[i
];
1708 if (var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) || MONO_TYPE_ISSTRUCT (var
->inst_vtype
)) {
1709 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
1710 CHECK_FAILURE (ctx
);
1711 /* Could be already created by an OP_VPHI */
1712 if (!ctx
->addresses
[var
->dreg
])
1713 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
1714 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
1718 for (i
= 0; i
< sig
->param_count
; ++i
) {
1719 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
1720 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
1722 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
1723 LLVMValueRef regs
[2];
1726 * Emit code to save the argument from the registers to
1727 * the real argument.
1729 pindex
= ctx
->pindexes
[i
];
1730 regs
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
1731 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
1732 regs
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
1736 ctx
->addresses
[reg
] = build_alloca (ctx
, sig
->params
[i
]);
1738 emit_reg_to_vtype (ctx
, builder
, sig
->params
[i
], ctx
->addresses
[reg
], ainfo
, regs
);
1740 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1741 /* Treat these as normal values */
1742 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1744 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
1745 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, ctx
->pindexes
[i
]);
1747 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1748 /* Treat these as normal values */
1749 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1752 ctx
->values
[reg
] = convert (ctx
, ctx
->values
[reg
], llvm_type_to_stack_type (type_to_llvm_type (ctx
, sig
->params
[i
])));
1757 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
1759 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
1760 for (i
= 0; i
< sig
->param_count
; ++i
)
1761 if (!MONO_TYPE_ISSTRUCT (sig
->params
[i
]))
1762 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
1764 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->generic_sharing_context
) {
1765 LLVMValueRef this_alloc
;
1768 * The exception handling code needs the location where the this argument was
1769 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1770 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1771 * location into the LSDA.
1773 this_alloc
= mono_llvm_build_alloca (builder
, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
1774 /* This volatile store will keep the alloca alive */
1775 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
);
1777 set_metadata_flag (this_alloc
, "mono.this");
1780 if (cfg
->rgctx_var
) {
1781 LLVMValueRef rgctx_alloc
, store
;
1784 * We handle the rgctx arg similarly to the this pointer.
1786 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
1787 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
1788 /* This volatile store will keep the alloca alive */
1789 store
= mono_llvm_build_store (builder
, ctx
->rgctx_arg
, rgctx_alloc
, TRUE
);
1791 set_metadata_flag (rgctx_alloc
, "mono.this");
1795 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1796 * it needs to continue normally, or return back to the exception handling system.
1798 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1799 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
))
1800 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
1801 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
) && bb
->in_scount
== 0) {
1805 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
1806 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
1807 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
1809 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
1812 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1813 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1814 * LLVM optimizer passes.
1816 sprintf (name
, "BB_%d_CALL_HANDLER_TARGET", bb
->block_num
);
1817 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
1825 /* Have to export this for AOT */
1827 mono_personality (void);
1830 mono_personality (void)
1833 g_assert_not_reached ();
1837 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
1839 MonoCompile
*cfg
= ctx
->cfg
;
1840 LLVMModuleRef module
= ctx
->module
;
1841 LLVMValueRef
*values
= ctx
->values
;
1842 LLVMValueRef
*addresses
= ctx
->addresses
;
1843 MonoCallInst
*call
= (MonoCallInst
*)ins
;
1844 MonoMethodSignature
*sig
= call
->signature
;
1845 LLVMValueRef callee
, lcall
;
1847 LLVMCallInfo
*cinfo
;
1851 LLVMTypeRef llvm_sig
;
1853 gboolean
virtual, calli
;
1854 LLVMBuilderRef builder
= *builder_ref
;
1857 if (call
->signature
->call_convention
!= MONO_CALL_DEFAULT
)
1858 LLVM_FAILURE (ctx
, "non-default callconv");
1860 if (call
->rgctx_arg_reg
&& !IS_LLVM_MONO_BRANCH
)
1861 LLVM_FAILURE (ctx
, "rgctx reg in call");
1863 if (call
->rgctx_reg
&& !IS_LLVM_MONO_BRANCH
) {
1865 * It might be possible to support this by creating a static rgctx trampoline, but
1866 * common_call_trampoline () would patch callsites to call the trampoline, which
1867 * would be incorrect if the rgctx arg is computed dynamically.
1869 LLVM_FAILURE (ctx
, "rgctx reg");
1872 cinfo
= call
->cinfo
;
1873 if (call
->rgctx_arg_reg
)
1874 cinfo
->rgctx_arg
= TRUE
;
1875 if (call
->imt_arg_reg
)
1876 cinfo
->imt_arg
= TRUE
;
1878 vretaddr
= cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
;
1880 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
, &sinfo
);
1881 CHECK_FAILURE (ctx
);
1883 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
);
1884 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
);
1886 /* FIXME: Avoid creating duplicate methods */
1888 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
1892 if (cfg
->compile_aot
) {
1893 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
1895 LLVM_FAILURE (ctx
, "can't encode patch");
1897 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1900 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1902 LLVMAddGlobalMapping (ee
, callee
, target
);
1907 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
1913 memset (&ji, 0, sizeof (ji));
1914 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1915 ji.data.target = info->name;
1917 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1919 if (cfg
->compile_aot
) {
1920 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
1922 LLVM_FAILURE (ctx
, "can't encode patch");
1924 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1925 target
= (gpointer
)mono_icall_get_wrapper (info
);
1926 LLVMAddGlobalMapping (ee
, callee
, target
);
1929 if (cfg
->compile_aot
) {
1931 if (cfg
->abs_patches
) {
1932 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1934 callee
= get_plt_entry (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
1936 LLVM_FAILURE (ctx
, "can't encode patch");
1940 LLVM_FAILURE (ctx
, "aot");
1942 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1944 if (cfg
->abs_patches
) {
1945 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1948 * FIXME: Some trampolines might have
1949 * their own calling convention on some platforms.
1951 #ifndef TARGET_AMD64
1952 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
)
1953 LLVM_FAILURE (ctx
, "trampoline with own cconv");
1955 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
);
1956 LLVMAddGlobalMapping (ee
, callee
, target
);
1960 LLVMAddGlobalMapping (ee
, callee
, (gpointer
)call
->fptr
);
1966 int size
= sizeof (gpointer
);
1969 g_assert (ins
->inst_offset
% size
== 0);
1970 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
1973 * When using the llvm mono branch, we can support IMT directly, otherwise
1974 * we need to call a trampoline.
1976 if (call
->method
&& call
->method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
&& !IS_LLVM_MONO_BRANCH
) {
1977 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1978 if (cfg
->compile_aot
) {
1979 MonoJumpInfoImtTramp
*imt_tramp
= g_new0 (MonoJumpInfoImtTramp
, 1);
1980 imt_tramp
->method
= call
->method
;
1981 imt_tramp
->vt_offset
= call
->inst
.inst_offset
;
1983 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE
, imt_tramp
);
1985 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1986 target
= mono_create_llvm_imt_trampoline (cfg
->domain
, call
->method
, call
->inst
.inst_offset
);
1987 LLVMAddGlobalMapping (ee
, callee
, target
);
1990 /* No support for passing the IMT argument */
1991 LLVM_FAILURE (ctx
, "imt");
1994 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
1997 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
1999 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
2004 * Collect and convert arguments
2006 len
= sizeof (LLVMValueRef
) * ((sig
->param_count
* 2) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
);
2007 args
= alloca (len
);
2008 memset (args
, 0, len
);
2009 l
= call
->out_ireg_args
;
2011 if (IS_LLVM_MONO_BRANCH
) {
2012 if (call
->rgctx_arg_reg
) {
2013 g_assert (values
[call
->rgctx_arg_reg
]);
2014 args
[sinfo
.rgctx_arg_pindex
] = values
[call
->rgctx_arg_reg
];
2016 if (call
->imt_arg_reg
) {
2017 g_assert (values
[call
->imt_arg_reg
]);
2018 args
[sinfo
.imt_arg_pindex
] = values
[call
->imt_arg_reg
];
2023 if (!addresses
[call
->inst
.dreg
])
2024 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
2025 args
[sinfo
.vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
2028 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
2031 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
] : NULL
;
2035 pindex
= sinfo
.this_arg_pindex
;
2037 pindex
= sinfo
.pindexes
[i
- 1];
2039 pindex
= sinfo
.pindexes
[i
];
2042 regpair
= (guint32
)(gssize
)(l
->data
);
2043 reg
= regpair
& 0xffffff;
2044 args
[pindex
] = values
[reg
];
2045 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2047 LLVMValueRef regs
[2];
2052 g_assert (addresses
[reg
]);
2054 emit_vtype_to_reg (ctx
, builder
, sig
->params
[i
- sig
->hasthis
], addresses
[reg
], ainfo
, regs
, &nregs
);
2055 for (j
= 0; j
< nregs
; ++j
)
2056 args
[pindex
++] = regs
[j
];
2059 // FIXME: Get rid of the VMOVE
2060 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
2061 g_assert (addresses
[reg
]);
2062 args
[pindex
] = addresses
[reg
];
2064 g_assert (args
[pindex
]);
2065 if (i
== 0 && sig
->hasthis
)
2066 args
[pindex
] = convert (ctx
, args
[pindex
], IntPtrType ());
2068 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, sig
->params
[i
- sig
->hasthis
]));
2074 // FIXME: Align call sites
2080 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
2082 #ifdef LLVM_MONO_BRANCH
2084 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2086 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2087 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
2089 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2090 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
2092 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
2094 if (call
->rgctx_arg_reg
)
2095 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.rgctx_arg_pindex
, LLVMInRegAttribute
);
2096 if (call
->imt_arg_reg
)
2097 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.imt_arg_pindex
, LLVMInRegAttribute
);
2100 /* Add byval attributes if needed */
2101 for (i
= 0; i
< sig
->param_count
; ++i
) {
2102 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
+ sig
->hasthis
] : NULL
;
2104 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
) {
2105 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.pindexes
[i
], LLVMByValAttribute
);
2110 * Convert the result
2112 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2113 LLVMValueRef regs
[2];
2115 if (!addresses
[ins
->dreg
])
2116 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
2118 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
2119 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
2120 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
2122 emit_reg_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
2123 } else if (sig
->ret
->type
!= MONO_TYPE_VOID
&& !vretaddr
) {
2124 /* If the method returns an unsigned value, need to zext it */
2126 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
));
2129 *builder_ref
= ctx
->builder
;
2131 g_free (sinfo
.pindexes
);
2139 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
2141 MonoCompile
*cfg
= ctx
->cfg
;
2142 MonoMethodSignature
*sig
= ctx
->sig
;
2143 LLVMValueRef method
= ctx
->lmethod
;
2144 LLVMValueRef
*values
= ctx
->values
;
2145 LLVMValueRef
*addresses
= ctx
->addresses
;
2147 LLVMCallInfo
*linfo
= ctx
->linfo
;
2148 LLVMModuleRef module
= ctx
->module
;
2149 BBInfo
*bblocks
= ctx
->bblocks
;
2151 LLVMBasicBlockRef cbb
;
2152 LLVMBuilderRef builder
;
2153 gboolean has_terminator
;
2155 LLVMValueRef lhs
, rhs
;
2157 cbb
= get_bb (ctx
, bb
);
2158 builder
= create_builder (ctx
);
2159 ctx
->builder
= builder
;
2160 LLVMPositionBuilderAtEnd (builder
, cbb
);
2162 if (bb
== cfg
->bb_entry
)
2163 emit_entry_bb (ctx
, builder
);
2164 CHECK_FAILURE (ctx
);
2166 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
2168 LLVMValueRef eh_selector
, eh_exception
, personality
, args
[4];
2169 LLVMBasicBlockRef target_bb
;
2171 static gint32 mapping_inited
;
2172 static int ti_generator
;
2175 LLVMValueRef type_info
;
2178 if (!bblocks
[bb
->block_num
].invoke_target
) {
2180 * LLVM asserts if llvm.eh.selector is called from a bblock which
2181 * doesn't have an invoke pointing at it.
2182 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2184 LLVM_FAILURE (ctx
, "handler without invokes");
2187 eh_selector
= LLVMGetNamedFunction (module
, eh_selector_name
);
2189 if (cfg
->compile_aot
) {
2190 /* Use a dummy personality function */
2191 personality
= LLVMGetNamedFunction (module
, "mono_aot_personality");
2192 g_assert (personality
);
2194 personality
= LLVMGetNamedFunction (module
, "mono_personality");
2195 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
2196 LLVMAddGlobalMapping (ee
, personality
, mono_personality
);
2199 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
2201 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
2204 * Create the type info
2206 sprintf (ti_name
, "type_info_%d", ti_generator
);
2209 if (cfg
->compile_aot
) {
2210 /* decode_eh_frame () in aot-runtime.c will decode this */
2211 type_info
= LLVMAddGlobal (module
, LLVMInt32Type (), ti_name
);
2212 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
2214 LLVMSetLinkage (type_info
, LLVMPrivateLinkage
);
2215 LLVMSetVisibility (type_info
, LLVMHiddenVisibility
);
2218 * Enabling this causes llc to crash:
2219 * http://llvm.org/bugs/show_bug.cgi?id=6102
2221 //LLVM_FAILURE (ctx, "aot+clauses");
2224 * After the cfg mempool is freed, the type info will point to stale memory,
2225 * but this is not a problem, since we decode it once in exception_cb during
2228 ti
= mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
2229 *(gint32
*)ti
= clause_index
;
2231 type_info
= LLVMAddGlobal (module
, i8ptr
, ti_name
);
2233 LLVMAddGlobalMapping (ee
, type_info
, ti
);
2236 args
[0] = LLVMConstNull (i8ptr
);
2237 args
[1] = LLVMConstBitCast (personality
, i8ptr
);
2238 args
[2] = type_info
;
2239 LLVMBuildCall (builder
, eh_selector
, args
, 3, "");
2241 /* Store the exception into the exvar */
2242 if (bb
->in_scount
== 1) {
2243 g_assert (bb
->in_scount
== 1);
2244 exvar
= bb
->in_stack
[0];
2246 eh_exception
= LLVMGetNamedFunction (module
, "llvm.eh.exception");
2248 // FIXME: This is shared with filter clauses ?
2249 g_assert (!values
[exvar
->dreg
]);
2250 values
[exvar
->dreg
] = LLVMBuildCall (builder
, eh_exception
, NULL
, 0, "");
2251 emit_volatile_store (ctx
, exvar
->dreg
);
2254 /* Start a new bblock which CALL_HANDLER can branch to */
2255 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
2257 LLVMBuildBr (builder
, target_bb
);
2259 ctx
->builder
= builder
= create_builder (ctx
);
2260 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
2262 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
2266 has_terminator
= FALSE
;
2267 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
2268 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
2270 char dname_buf
[128];
2273 /* There could be instructions after a terminator, skip them */
2276 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
2277 sprintf (dname_buf
, "t%d", ins
->dreg
);
2281 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
2282 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
2284 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2285 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
2287 /* It is ok for SETRET to have an uninitialized argument */
2288 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
)
2289 LLVM_FAILURE (ctx
, "sreg1");
2290 lhs
= values
[ins
->sreg1
];
2296 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
2297 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
2298 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2299 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
2301 if (!values
[ins
->sreg2
])
2302 LLVM_FAILURE (ctx
, "sreg2");
2303 rhs
= values
[ins
->sreg2
];
2309 //mono_print_ins (ins);
2310 switch (ins
->opcode
) {
2313 case OP_LIVERANGE_START
:
2314 case OP_LIVERANGE_END
:
2317 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
2320 #if SIZEOF_VOID_P == 4
2321 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2323 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
2327 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
2330 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
2333 LLVMBuildBr (builder
, get_bb (ctx
, ins
->inst_target_bb
));
2334 has_terminator
= TRUE
;
2340 LLVMBasicBlockRef new_bb
;
2341 LLVMBuilderRef new_builder
;
2343 // The default branch is already handled
2344 // FIXME: Handle it here
2346 /* Start new bblock */
2347 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
2348 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
2350 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2351 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
2352 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
2353 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
2355 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
2358 new_builder
= create_builder (ctx
);
2359 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
2360 LLVMBuildUnreachable (new_builder
);
2362 has_terminator
= TRUE
;
2363 g_assert (!ins
->next
);
2369 if (linfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2370 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
2371 LLVMValueRef part1
, retval
;
2374 size
= get_vtype_size (sig
->ret
);
2376 g_assert (addresses
[ins
->sreg1
]);
2378 g_assert (linfo
->ret
.pair_storage
[0] == LLVMArgInIReg
);
2379 g_assert (linfo
->ret
.pair_storage
[1] == LLVMArgNone
);
2381 part1
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMIntType (size
* 8), 0), ""), ""), IntPtrType ());
2383 retval
= LLVMBuildInsertValue (builder
, LLVMGetUndef (ret_type
), part1
, 0, "");
2385 LLVMBuildRet (builder
, retval
);
2389 if (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
) {
2390 LLVMBuildRetVoid (builder
);
2394 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
2396 * The method did not set its return value, probably because it
2397 * ends with a throw.
2400 LLVMBuildRetVoid (builder
);
2402 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
2404 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
2406 has_terminator
= TRUE
;
2412 case OP_ICOMPARE_IMM
:
2413 case OP_LCOMPARE_IMM
:
2414 case OP_COMPARE_IMM
: {
2418 if (ins
->next
->opcode
== OP_NOP
)
2421 if (ins
->next
->opcode
== OP_BR
)
2422 /* The comparison result is not needed */
2425 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
2427 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
2428 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2429 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2431 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2432 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2433 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2435 if (ins
->opcode
== OP_LCOMPARE
) {
2436 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2437 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
2439 if (ins
->opcode
== OP_ICOMPARE
) {
2440 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2441 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2445 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2446 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
2447 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
2448 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
2451 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2452 if (ins
->opcode
== OP_FCOMPARE
)
2453 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2454 else if (ins
->opcode
== OP_COMPARE_IMM
)
2455 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
2456 else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2457 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
2458 /* The immediate is encoded in two fields */
2459 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
2460 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
2462 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
2465 else if (ins
->opcode
== OP_COMPARE
)
2466 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
2468 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
2470 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
2471 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
2473 * If the target bb contains PHI instructions, LLVM requires
2474 * two PHI entries for this bblock, while we only generate one.
2475 * So convert this to an unconditional bblock. (bxc #171).
2477 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
2479 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
2481 has_terminator
= TRUE
;
2482 } else if (MONO_IS_SETCC (ins
->next
)) {
2483 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
2485 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2487 /* Add stores for volatile variables */
2488 emit_volatile_store (ctx
, ins
->next
->dreg
);
2489 } else if (MONO_IS_COND_EXC (ins
->next
)) {
2490 emit_cond_system_exception (ctx
, bb
, ins
->next
->inst_p1
, cmp
);
2491 CHECK_FAILURE (ctx
);
2492 builder
= ctx
->builder
;
2494 LLVM_FAILURE (ctx
, "next");
2508 rel
= mono_opcode_to_cond (ins
->opcode
);
2510 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2511 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2519 gboolean empty
= TRUE
;
2521 /* Check that all input bblocks really branch to us */
2522 for (i
= 0; i
< bb
->in_count
; ++i
) {
2523 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
2524 ins
->inst_phi_args
[i
+ 1] = -1;
2530 /* LLVM doesn't like phi instructions with zero operands */
2531 ctx
->is_dead
[ins
->dreg
] = TRUE
;
2535 /* Created earlier, insert it now */
2536 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
2538 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
2539 int sreg1
= ins
->inst_phi_args
[i
+ 1];
2543 * Count the number of times the incoming bblock branches to us,
2544 * since llvm requires a separate entry for each.
2546 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
2547 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
2550 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
2551 if (switch_ins
->inst_many_bb
[j
] == bb
)
2558 /* Remember for later */
2559 for (j
= 0; j
< count
; ++j
) {
2560 PhiNode
*node
= mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
2563 node
->in_bb
= bb
->in_bb
[i
];
2565 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
);
2575 values
[ins
->dreg
] = lhs
;
2578 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
2581 values
[ins
->dreg
] = lhs
;
2583 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
2585 * This is added by the spilling pass in case of the JIT,
2586 * but we have to do it ourselves.
2588 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
2622 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2623 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2625 switch (ins
->opcode
) {
2628 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
2632 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
2636 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
2640 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
2644 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
2648 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
2652 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
2655 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
2659 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
2663 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
2667 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
2671 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
2675 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
2679 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
2683 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
2686 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
2689 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
2693 g_assert_not_reached ();
2700 case OP_IREM_UN_IMM
:
2702 case OP_IDIV_UN_IMM
:
2708 case OP_ISHR_UN_IMM
:
2717 case OP_LSHR_UN_IMM
:
2725 if (spec
[MONO_INST_SRC1
] == 'l') {
2726 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2728 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2731 #if SIZEOF_VOID_P == 4
2732 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
2733 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2736 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2737 lhs
= convert (ctx
, lhs
, IntPtrType ());
2738 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
2739 switch (ins
->opcode
) {
2743 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
2747 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
2751 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
2755 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
2757 case OP_IDIV_UN_IMM
:
2758 case OP_LDIV_UN_IMM
:
2759 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
2763 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
2765 case OP_IREM_UN_IMM
:
2766 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
2771 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
2775 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
2779 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
2784 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
2789 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
2791 case OP_ISHR_UN_IMM
:
2792 /* This is used to implement conv.u4, so the lhs could be an i8 */
2793 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2794 imm
= convert (ctx
, imm
, LLVMInt32Type ());
2795 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2797 case OP_LSHR_UN_IMM
:
2798 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2801 g_assert_not_reached ();
2806 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
2809 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
2812 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
2813 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
2816 guint32 v
= 0xffffffff;
2817 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), lhs
, dname
);
2821 guint64 v
= 0xffffffffffffffffLL
;
2822 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
2825 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2827 LLVMValueRef v1
, v2
;
2829 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
2830 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
2831 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
2836 case OP_ICONV_TO_I1
:
2837 case OP_ICONV_TO_I2
:
2838 case OP_ICONV_TO_I4
:
2839 case OP_ICONV_TO_U1
:
2840 case OP_ICONV_TO_U2
:
2841 case OP_ICONV_TO_U4
:
2842 case OP_LCONV_TO_I1
:
2843 case OP_LCONV_TO_I2
:
2844 case OP_LCONV_TO_U1
:
2845 case OP_LCONV_TO_U2
:
2846 case OP_LCONV_TO_U4
: {
2849 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
);
2851 /* Have to do two casts since our vregs have type int */
2852 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
2854 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
2856 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
2859 case OP_ICONV_TO_I8
:
2860 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2862 case OP_ICONV_TO_U8
:
2863 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2865 case OP_FCONV_TO_I4
:
2866 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
2868 case OP_FCONV_TO_I1
:
2869 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2871 case OP_FCONV_TO_U1
:
2872 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2874 case OP_FCONV_TO_I2
:
2875 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2877 case OP_FCONV_TO_U2
:
2878 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2880 case OP_FCONV_TO_I8
:
2881 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
2884 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
2886 case OP_ICONV_TO_R8
:
2887 case OP_LCONV_TO_R8
:
2888 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2890 case OP_LCONV_TO_R_UN
:
2891 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2893 #if SIZEOF_VOID_P == 4
2896 case OP_LCONV_TO_I4
:
2897 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2899 case OP_ICONV_TO_R4
:
2900 case OP_LCONV_TO_R4
:
2901 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
2902 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2904 case OP_FCONV_TO_R4
:
2905 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
2906 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2909 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2912 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2915 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2917 case OP_LOCALLOC_IMM
: {
2920 guint32 size
= ins
->inst_imm
;
2921 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
2923 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
2925 if (ins
->flags
& MONO_INST_INIT
) {
2926 LLVMValueRef args
[5];
2929 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2930 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
2931 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2932 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2933 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2936 values
[ins
->dreg
] = v
;
2940 LLVMValueRef v
, size
;
2942 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
), "");
2944 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
2946 if (ins
->flags
& MONO_INST_INIT
) {
2947 LLVMValueRef args
[5];
2950 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2952 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2953 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2954 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2956 values
[ins
->dreg
] = v
;
2960 case OP_LOADI1_MEMBASE
:
2961 case OP_LOADU1_MEMBASE
:
2962 case OP_LOADI2_MEMBASE
:
2963 case OP_LOADU2_MEMBASE
:
2964 case OP_LOADI4_MEMBASE
:
2965 case OP_LOADU4_MEMBASE
:
2966 case OP_LOADI8_MEMBASE
:
2967 case OP_LOADR4_MEMBASE
:
2968 case OP_LOADR8_MEMBASE
:
2969 case OP_LOAD_MEMBASE
:
2977 LLVMValueRef base
, index
, addr
;
2979 gboolean sext
= FALSE
, zext
= FALSE
;
2980 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
2982 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2987 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
)) {
2988 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
2993 if (ins
->inst_offset
== 0) {
2995 } else if (ins
->inst_offset
% size
!= 0) {
2996 /* Unaligned load */
2997 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2998 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3000 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3001 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
3005 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
3007 values
[ins
->dreg
] = emit_load (ctx
, bb
, &builder
, size
, addr
, dname
, is_volatile
);
3009 if (!is_volatile
&& (ins
->flags
& MONO_INST_CONSTANT_LOAD
)) {
3011 * These will signal LLVM that these loads do not alias any stores, and
3012 * they can't fail, allowing them to be hoisted out of loops.
3014 set_metadata_flag (values
[ins
->dreg
], "mono.noalias");
3015 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
3019 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
3021 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
3022 else if (ins
->opcode
== OP_LOADR4_MEMBASE
)
3023 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
3027 case OP_STOREI1_MEMBASE_REG
:
3028 case OP_STOREI2_MEMBASE_REG
:
3029 case OP_STOREI4_MEMBASE_REG
:
3030 case OP_STOREI8_MEMBASE_REG
:
3031 case OP_STORER4_MEMBASE_REG
:
3032 case OP_STORER8_MEMBASE_REG
:
3033 case OP_STORE_MEMBASE_REG
: {
3035 LLVMValueRef index
, addr
;
3037 gboolean sext
= FALSE
, zext
= FALSE
;
3038 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3040 if (!values
[ins
->inst_destbasereg
])
3041 LLVM_FAILURE (ctx
, "inst_destbasereg");
3043 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3045 if (ins
->inst_offset
% size
!= 0) {
3046 /* Unaligned store */
3047 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3048 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3050 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3051 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3053 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), is_volatile
);
3057 case OP_STOREI1_MEMBASE_IMM
:
3058 case OP_STOREI2_MEMBASE_IMM
:
3059 case OP_STOREI4_MEMBASE_IMM
:
3060 case OP_STOREI8_MEMBASE_IMM
:
3061 case OP_STORE_MEMBASE_IMM
: {
3063 LLVMValueRef index
, addr
;
3065 gboolean sext
= FALSE
, zext
= FALSE
;
3066 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3068 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3070 if (ins
->inst_offset
% size
!= 0) {
3071 /* Unaligned store */
3072 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3073 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3075 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3076 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3078 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), addr
, is_volatile
);
3083 emit_load (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
3085 case OP_OUTARG_VTRETADDR
:
3092 case OP_VOIDCALL_MEMBASE
:
3093 case OP_CALL_MEMBASE
:
3094 case OP_LCALL_MEMBASE
:
3095 case OP_FCALL_MEMBASE
:
3096 case OP_VCALL_MEMBASE
:
3097 case OP_VOIDCALL_REG
:
3101 case OP_VCALL_REG
: {
3102 process_call (ctx
, bb
, &builder
, ins
);
3103 CHECK_FAILURE (ctx
);
3108 LLVMValueRef indexes
[2];
3110 LLVMValueRef got_entry_addr
;
3113 * FIXME: Can't allocate from the cfg mempool since that is freed if
3114 * the LLVM compile fails.
3116 ji
= g_new0 (MonoJumpInfo
, 1);
3117 ji
->type
= (MonoJumpInfoType
)ins
->inst_i1
;
3118 ji
->data
.target
= ins
->inst_p0
;
3120 ji
= mono_aot_patch_info_dup (ji
);
3122 ji
->next
= cfg
->patch_info
;
3123 cfg
->patch_info
= ji
;
3125 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3126 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
3128 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3129 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
3130 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->lmodule
->got_var
, indexes
, 2, "");
3132 // FIXME: This doesn't work right now, because it must be
3133 // paired with an invariant.end, and even then, its only in effect
3134 // inside its basic block
3137 LLVMValueRef args
[3];
3138 LLVMValueRef ptr
, val
;
3140 ptr
= LLVMBuildBitCast (builder
, got_entry_addr
, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3142 args
[0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer
), FALSE
);
3144 val
= LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.invariant.start"), args
, 2, "");
3148 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, dname
);
3151 case OP_NOT_REACHED
:
3152 LLVMBuildUnreachable (builder
);
3153 has_terminator
= TRUE
;
3154 g_assert (bb
->block_num
< cfg
->max_block_num
);
3155 ctx
->unreachable
[bb
->block_num
] = TRUE
;
3156 /* Might have instructions after this */
3158 MonoInst
*next
= ins
->next
;
3160 * FIXME: If later code uses the regs defined by these instructions,
3161 * compilation will fail.
3163 MONO_DELETE_INS (bb
, next
);
3167 MonoInst
*var
= ins
->inst_p0
;
3169 values
[ins
->dreg
] = addresses
[var
->dreg
];
3173 LLVMValueRef args
[1];
3175 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3176 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sin.f64"), args
, 1, dname
);
3180 LLVMValueRef args
[1];
3182 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3183 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.cos.f64"), args
, 1, dname
);
3187 LLVMValueRef args
[1];
3190 /* This no longer seems to happen */
3192 * LLVM optimizes sqrt(nan) into undefined in
3193 * lib/Analysis/ConstantFolding.cpp
3194 * Also, sqrt(NegativeInfinity) is optimized into 0.
3196 LLVM_FAILURE (ctx
, "sqrt");
3199 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sqrt.f64"), args
, 1, dname
);
3203 LLVMValueRef args
[1];
3206 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "fabs"), args
, 1, dname
);
3220 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3221 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3223 switch (ins
->opcode
) {
3226 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
3230 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
3234 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
3238 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
3241 g_assert_not_reached ();
3244 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3247 case OP_ATOMIC_EXCHANGE_I4
: {
3248 LLVMValueRef args
[2];
3250 g_assert (ins
->inst_offset
== 0);
3252 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3254 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i32.p0i32"), args
, 2, dname
);
3257 case OP_ATOMIC_EXCHANGE_I8
: {
3258 LLVMValueRef args
[2];
3260 g_assert (ins
->inst_offset
== 0);
3262 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3263 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3264 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i64.p0i64"), args
, 2, dname
);
3267 case OP_ATOMIC_ADD_NEW_I4
: {
3268 LLVMValueRef args
[2];
3270 g_assert (ins
->inst_offset
== 0);
3272 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3274 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i32.p0i32"), args
, 2, ""), args
[1], dname
);
3277 case OP_ATOMIC_ADD_NEW_I8
: {
3278 LLVMValueRef args
[2];
3280 g_assert (ins
->inst_offset
== 0);
3282 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3283 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3284 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i64.p0i64"), args
, 2, ""), args
[1], dname
);
3287 case OP_ATOMIC_CAS_I4
:
3288 case OP_ATOMIC_CAS_I8
: {
3289 LLVMValueRef args
[3];
3291 const char *intrins
;
3293 if (ins
->opcode
== OP_ATOMIC_CAS_I4
) {
3294 t
= LLVMInt32Type ();
3295 intrins
= "llvm.atomic.cmp.swap.i32.p0i32";
3297 t
= LLVMInt64Type ();
3298 intrins
= "llvm.atomic.cmp.swap.i64.p0i64";
3301 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
3303 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
3305 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
3306 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, intrins
), args
, 3, dname
);
3309 case OP_MEMORY_BARRIER
: {
3310 LLVMValueRef args
[5];
3313 /* Not yet supported by llc on arm */
3314 LLVM_FAILURE (ctx
, "memory-barrier+arm");
3317 for (i
= 0; i
< 5; ++i
)
3318 args
[i
] = LLVMConstInt (LLVMInt1Type (), TRUE
, TRUE
);
3320 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.memory.barrier"), args
, 5, "");
3323 case OP_RELAXED_NOP
: {
3324 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3325 if (IS_LLVM_MONO_BRANCH
)
3326 emit_call (ctx
, bb
, &builder
, LLVMGetNamedFunction (ctx
->module
, "llvm.x86.sse2.pause"), NULL
, 0);
3328 /* No way to get LLVM to emit this */
3329 LLVM_FAILURE (ctx
, "relaxed_nop");
3336 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3338 // 257 == FS segment register
3339 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
3341 // 256 == GS segment register
3342 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
3346 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
3348 LLVM_FAILURE (ctx
, "opcode tls-get");
3358 case OP_IADD_OVF_UN
:
3360 case OP_ISUB_OVF_UN
:
3362 case OP_IMUL_OVF_UN
:
3363 #if SIZEOF_VOID_P == 8
3365 case OP_LADD_OVF_UN
:
3367 case OP_LSUB_OVF_UN
:
3369 case OP_LMUL_OVF_UN
:
3372 LLVMValueRef args
[2], val
, ovf
, func
;
3374 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
3375 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
3376 func
= LLVMGetNamedFunction (module
, ovf_op_to_intrins (ins
->opcode
));
3378 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
3379 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
3380 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
3381 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
3382 CHECK_FAILURE (ctx
);
3383 builder
= ctx
->builder
;
3389 * We currently model them using arrays. Promotion to local vregs is
3390 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3391 * so we always have an entry in cfg->varinfo for them.
3392 * FIXME: Is this needed ?
3395 MonoClass
*klass
= ins
->klass
;
3396 LLVMValueRef args
[5];
3400 LLVM_FAILURE (ctx
, "!klass");
3404 if (!addresses
[ins
->dreg
])
3405 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3406 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3407 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
3408 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3410 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3411 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3412 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
3416 case OP_STOREV_MEMBASE
:
3417 case OP_LOADV_MEMBASE
:
3419 MonoClass
*klass
= ins
->klass
;
3420 LLVMValueRef src
, dst
, args
[5];
3421 gboolean done
= FALSE
;
3425 LLVM_FAILURE (ctx
, "!klass");
3429 switch (ins
->opcode
) {
3430 case OP_STOREV_MEMBASE
:
3431 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
) {
3432 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3433 LLVM_FAILURE (ctx
, "storev_membase + write barriers");
3436 if (!addresses
[ins
->sreg1
]) {
3438 g_assert (values
[ins
->sreg1
]);
3439 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));
3440 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
3443 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3444 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3447 case OP_LOADV_MEMBASE
:
3448 if (!addresses
[ins
->dreg
])
3449 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3450 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3451 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3454 if (!addresses
[ins
->sreg1
])
3455 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
3456 if (!addresses
[ins
->dreg
])
3457 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3458 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3459 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3462 g_assert_not_reached ();
3464 CHECK_FAILURE (ctx
);
3471 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3472 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3474 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3475 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3476 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memcpy_func_name
), args
, memcpy_param_count
, "");
3479 case OP_LLVM_OUTARG_VT
:
3480 if (!addresses
[ins
->sreg1
]) {
3481 addresses
[ins
->sreg1
] = build_alloca (ctx
, &ins
->klass
->byval_arg
);
3482 g_assert (values
[ins
->sreg1
]);
3483 LLVMBuildStore (builder
, values
[ins
->sreg1
], addresses
[ins
->sreg1
]);
3485 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
3491 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3493 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
3496 case OP_LOADX_MEMBASE
: {
3497 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
3500 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3501 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
3504 case OP_STOREX_MEMBASE
: {
3505 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
3508 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3509 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
3516 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
3520 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
3526 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
3530 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
3534 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
3538 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
3541 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
3544 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
3547 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
3551 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
3564 switch (ins
->opcode
) {
3569 t
= LLVMVectorType (LLVMInt32Type (), 4);
3570 rt
= LLVMVectorType (LLVMFloatType (), 4);
3576 t
= LLVMVectorType (LLVMInt64Type (), 2);
3577 rt
= LLVMVectorType (LLVMDoubleType (), 2);
3580 t
= LLVMInt32Type ();
3581 rt
= LLVMInt32Type ();
3582 g_assert_not_reached ();
3585 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3586 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
3587 switch (ins
->opcode
) {
3590 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
3594 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
3598 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
3602 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
3605 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
3629 case OP_PADDB_SAT_UN
:
3630 case OP_PADDW_SAT_UN
:
3631 case OP_PSUBB_SAT_UN
:
3632 case OP_PSUBW_SAT_UN
:
3645 case OP_PMULW_HIGH_UN
: {
3646 LLVMValueRef args
[2];
3651 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3659 case OP_EXTRACTX_U2
:
3661 case OP_EXTRACT_U1
: {
3663 gboolean zext
= FALSE
;
3665 t
= simd_op_to_llvm_type (ins
->opcode
);
3667 switch (ins
->opcode
) {
3675 case OP_EXTRACTX_U2
:
3680 t
= LLVMInt32Type ();
3681 g_assert_not_reached ();
3684 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3685 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
3687 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
3696 case OP_EXPAND_R8
: {
3697 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3698 LLVMValueRef mask
[16], v
;
3700 for (i
= 0; i
< 16; ++i
)
3701 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3703 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
3705 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3706 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
3711 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3714 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3717 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3720 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3723 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3726 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3737 case OP_EXTRACT_MASK
:
3744 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
3746 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
3750 case OP_ICONV_TO_R8_RAW
:
3751 /* Same as OP_ICONV_TO_R8 */
3752 values
[ins
->dreg
] = convert (ctx
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType ());
3757 LLVMValueRef args
[3];
3761 args
[2] = LLVMConstInt (LLVMInt8Type (), ins
->inst_c0
, FALSE
);
3763 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
3768 /* This is only used for implementing shifts by non-immediate */
3769 values
[ins
->dreg
] = lhs
;
3780 LLVMValueRef args
[3];
3783 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
3785 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3796 case OP_PSHLQ_REG
: {
3797 LLVMValueRef args
[3];
3800 args
[1] = values
[ins
->sreg2
];
3802 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3809 case OP_PSHUFLEW_LOW
:
3810 case OP_PSHUFLEW_HIGH
: {
3812 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[4];
3813 int i
, mask_size
= 0;
3814 int imask
= ins
->inst_c0
;
3816 /* Convert the x86 shuffle mask to LLVM's */
3817 switch (ins
->opcode
) {
3820 mask
[0] = ((imask
>> 0) & 3);
3821 mask
[1] = ((imask
>> 2) & 3);
3822 mask
[2] = ((imask
>> 4) & 3) + 4;
3823 mask
[3] = ((imask
>> 6) & 3) + 4;
3824 v1
= values
[ins
->sreg1
];
3825 v2
= values
[ins
->sreg2
];
3829 mask
[0] = ((imask
>> 0) & 1);
3830 mask
[1] = ((imask
>> 1) & 1) + 2;
3831 v1
= values
[ins
->sreg1
];
3832 v2
= values
[ins
->sreg2
];
3834 case OP_PSHUFLEW_LOW
:
3836 mask
[0] = ((imask
>> 0) & 3);
3837 mask
[1] = ((imask
>> 2) & 3);
3838 mask
[2] = ((imask
>> 4) & 3);
3839 mask
[3] = ((imask
>> 6) & 3);
3844 v1
= values
[ins
->sreg1
];
3845 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3847 case OP_PSHUFLEW_HIGH
:
3853 mask
[4] = 4 + ((imask
>> 0) & 3);
3854 mask
[5] = 4 + ((imask
>> 2) & 3);
3855 mask
[6] = 4 + ((imask
>> 4) & 3);
3856 mask
[7] = 4 + ((imask
>> 6) & 3);
3857 v1
= values
[ins
->sreg1
];
3858 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3862 mask
[0] = ((imask
>> 0) & 3);
3863 mask
[1] = ((imask
>> 2) & 3);
3864 mask
[2] = ((imask
>> 4) & 3);
3865 mask
[3] = ((imask
>> 6) & 3);
3866 v1
= values
[ins
->sreg1
];
3867 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3870 g_assert_not_reached ();
3872 for (i
= 0; i
< mask_size
; ++i
)
3873 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3875 values
[ins
->dreg
] =
3876 LLVMBuildShuffleVector (builder
, v1
, v2
,
3877 LLVMConstVector (mask_values
, mask_size
), dname
);
3881 case OP_UNPACK_LOWB
:
3882 case OP_UNPACK_LOWW
:
3883 case OP_UNPACK_LOWD
:
3884 case OP_UNPACK_LOWQ
:
3885 case OP_UNPACK_LOWPS
:
3886 case OP_UNPACK_LOWPD
:
3887 case OP_UNPACK_HIGHB
:
3888 case OP_UNPACK_HIGHW
:
3889 case OP_UNPACK_HIGHD
:
3890 case OP_UNPACK_HIGHQ
:
3891 case OP_UNPACK_HIGHPS
:
3892 case OP_UNPACK_HIGHPD
: {
3894 LLVMValueRef mask_values
[16];
3895 int i
, mask_size
= 0;
3896 gboolean low
= FALSE
;
3898 switch (ins
->opcode
) {
3899 case OP_UNPACK_LOWB
:
3903 case OP_UNPACK_LOWW
:
3907 case OP_UNPACK_LOWD
:
3908 case OP_UNPACK_LOWPS
:
3912 case OP_UNPACK_LOWQ
:
3913 case OP_UNPACK_LOWPD
:
3917 case OP_UNPACK_HIGHB
:
3920 case OP_UNPACK_HIGHW
:
3923 case OP_UNPACK_HIGHD
:
3924 case OP_UNPACK_HIGHPS
:
3927 case OP_UNPACK_HIGHQ
:
3928 case OP_UNPACK_HIGHPD
:
3932 g_assert_not_reached ();
3936 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3938 mask
[(i
* 2) + 1] = mask_size
+ i
;
3941 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3942 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
3943 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
3947 for (i
= 0; i
< mask_size
; ++i
)
3948 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3950 values
[ins
->dreg
] =
3951 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
3952 LLVMConstVector (mask_values
, mask_size
), dname
);
3957 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3958 LLVMValueRef v
, val
;
3960 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3961 val
= LLVMConstNull (t
);
3962 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3963 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
3965 values
[ins
->dreg
] = val
;
3969 case OP_DUPPS_HIGH
: {
3970 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3971 LLVMValueRef v1
, v2
, val
;
3974 if (ins
->opcode
== OP_DUPPS_LOW
) {
3975 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3976 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3978 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3979 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3981 val
= LLVMConstNull (t
);
3982 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3983 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3984 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3985 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3987 values
[ins
->dreg
] = val
;
3997 * EXCEPTION HANDLING
3999 case OP_IMPLICIT_EXCEPTION
:
4000 /* This marks a place where an implicit exception can happen */
4001 if (bb
->region
!= -1)
4002 LLVM_FAILURE (ctx
, "implicit-exception");
4006 MonoMethodSignature
*throw_sig
;
4007 LLVMValueRef callee
, arg
;
4008 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
4009 const char *icall_name
;
4011 callee
= rethrow
? ctx
->lmodule
->rethrow
: ctx
->lmodule
->throw;
4012 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4015 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
4016 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
4017 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
4018 if (cfg
->compile_aot
) {
4019 callee
= get_plt_entry (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
4021 callee
= LLVMAddFunction (module
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
));
4025 * LLVM doesn't push the exception argument, so we need a different
4028 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4030 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
4034 mono_memory_barrier ();
4036 ctx
->lmodule
->rethrow
= callee
;
4038 ctx
->lmodule
->throw = callee
;
4040 arg
= convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
4041 emit_call (ctx
, bb
, &builder
, callee
, &arg
, 1);
4044 case OP_CALL_HANDLER
: {
4046 * We don't 'call' handlers, but instead simply branch to them.
4047 * The code generated by ENDFINALLY will branch back to us.
4049 LLVMBasicBlockRef noex_bb
;
4051 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
4053 bb_list
= info
->call_handler_return_bbs
;
4056 * Set the indicator variable for the finally clause.
4058 lhs
= info
->finally_ind
;
4060 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
4062 /* Branch to the finally clause */
4063 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
4065 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
4066 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
4068 builder
= ctx
->builder
= create_builder (ctx
);
4069 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
4071 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
4074 case OP_START_HANDLER
: {
4077 case OP_ENDFINALLY
: {
4078 LLVMBasicBlockRef resume_bb
;
4079 MonoBasicBlock
*handler_bb
;
4080 LLVMValueRef val
, switch_ins
, callee
;
4084 handler_bb
= g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
4085 g_assert (handler_bb
);
4086 info
= &bblocks
[handler_bb
->block_num
];
4087 lhs
= info
->finally_ind
;
4090 bb_list
= info
->call_handler_return_bbs
;
4092 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
4094 /* Load the finally variable */
4095 val
= LLVMBuildLoad (builder
, lhs
, "");
4097 /* Reset the variable */
4098 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
4100 /* Branch to either resume_bb, or to the bblocks in bb_list */
4101 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
4103 * The other targets are added at the end to handle OP_CALL_HANDLER
4104 * opcodes processed later.
4106 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
4108 builder
= ctx
->builder
= create_builder (ctx
);
4109 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
4111 if (ctx
->cfg
->compile_aot
) {
4112 callee
= get_plt_entry (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
4114 callee
= LLVMGetNamedFunction (module
, "llvm_resume_unwind_trampoline");
4116 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
4118 LLVMBuildUnreachable (builder
);
4119 has_terminator
= TRUE
;
4125 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
4126 LLVM_FAILURE (ctx
, reason
);
4131 /* Convert the value to the type required by phi nodes */
4132 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
4133 if (!values
[ins
->dreg
])
4135 values
[ins
->dreg
] = addresses
[ins
->dreg
];
4137 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
4140 /* Add stores for volatile variables */
4141 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
4142 emit_volatile_store (ctx
, ins
->dreg
);
4145 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4146 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
4148 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
)
4149 LLVMBuildRetVoid (builder
);
4151 if (bb
== cfg
->bb_entry
)
4152 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
4161 * mono_llvm_check_method_supported:
4163 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4164 * compiling a method twice.
4167 mono_llvm_check_method_supported (MonoCompile
*cfg
)
4170 MonoMethodHeader *header = cfg->header;
4171 MonoExceptionClause *clause;
4175 if (cfg
->generic_sharing_context
&& !IS_LLVM_MONO_BRANCH
) {
4176 /* No way to obtain location info for this/rgctx */
4177 cfg
->exception_message
= g_strdup ("gshared");
4178 cfg
->disable_llvm
= TRUE
;
4181 if (cfg
->method
->save_lmf
) {
4182 cfg
->exception_message
= g_strdup ("lmf");
4183 cfg
->disable_llvm
= TRUE
;
4187 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4188 clause
= &header
->clauses
[i
];
4190 if (i
> 0 && clause
->try_offset
<= header
->clauses
[i
- 1].handler_offset
+ header
->clauses
[i
- 1].handler_len
) {
4192 * FIXME: Some tests still fail with nested clauses.
4194 cfg
->exception_message
= g_strdup ("nested clauses");
4195 cfg
->disable_llvm
= TRUE
;
4201 if (cfg
->method
->dynamic
) {
4202 cfg
->exception_message
= g_strdup ("dynamic.");
4203 cfg
->disable_llvm
= TRUE
;
4208 * mono_llvm_emit_method:
4210 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4213 mono_llvm_emit_method (MonoCompile
*cfg
)
4216 MonoMethodSignature
*sig
;
4218 LLVMTypeRef method_type
;
4219 LLVMValueRef method
= NULL
;
4221 LLVMValueRef
*values
;
4222 int i
, max_block_num
, bb_index
;
4223 gboolean last
= FALSE
;
4224 GPtrArray
*phi_values
;
4225 LLVMCallInfo
*linfo
;
4227 LLVMModuleRef module
;
4229 GPtrArray
*bblock_list
;
4230 MonoMethodHeader
*header
;
4231 MonoExceptionClause
*clause
;
4235 /* The code below might acquire the loader lock, so use it for global locking */
4236 mono_loader_lock ();
4238 /* Used to communicate with the callbacks */
4239 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
4241 ctx
= g_new0 (EmitContext
, 1);
4243 ctx
->mempool
= cfg
->mempool
;
4246 * This maps vregs to the LLVM instruction defining them
4248 values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4250 * This maps vregs for volatile variables to the LLVM instruction defining their
4253 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4254 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
4255 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
4256 phi_values
= g_ptr_array_new ();
4258 * This signals whenever the vreg was defined by a phi node with no input vars
4259 * (i.e. all its input bblocks end with NOT_REACHABLE).
4261 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
4262 /* Whenever the bblock is unreachable */
4263 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
4265 bblock_list
= g_ptr_array_new ();
4267 ctx
->values
= values
;
4268 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
4270 if (cfg
->compile_aot
) {
4271 ctx
->lmodule
= &aot_module
;
4272 method_name
= mono_aot_get_method_name (cfg
);
4273 cfg
->llvm_method_name
= g_strdup (method_name
);
4276 ctx
->lmodule
= &jit_module
;
4277 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
4280 module
= ctx
->module
= ctx
->lmodule
->module
;
4284 static int count
= 0;
4287 if (getenv ("LLVM_COUNT")) {
4288 if (count
== atoi (getenv ("LLVM_COUNT"))) {
4289 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
4293 if (count
> atoi (getenv ("LLVM_COUNT")))
4294 LLVM_FAILURE (ctx
, "");
4299 sig
= mono_method_signature (cfg
->method
);
4302 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4304 CHECK_FAILURE (ctx
);
4306 if (cfg
->rgctx_var
) {
4307 if (IS_LLVM_MONO_BRANCH
)
4308 linfo
->rgctx_arg
= TRUE
;
4310 LLVM_FAILURE (ctx
, "rgctx arg");
4312 method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
, &sinfo
);
4313 CHECK_FAILURE (ctx
);
4316 * This maps parameter indexes in the original signature to the indexes in
4317 * the LLVM signature.
4319 ctx
->pindexes
= sinfo
.pindexes
;
4321 method
= LLVMAddFunction (module
, method_name
, method_type
);
4322 ctx
->lmethod
= method
;
4324 #ifdef LLVM_MONO_BRANCH
4325 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
4327 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4329 LLVMAddFunctionAttr (method
, LLVMUWTableAttribute
);
4331 if (cfg
->compile_aot
) {
4332 LLVMSetLinkage (method
, LLVMInternalLinkage
);
4333 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
4335 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4338 if (cfg
->method
->save_lmf
)
4339 LLVM_FAILURE (ctx
, "lmf");
4341 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
)
4342 LLVM_FAILURE (ctx
, "pinvoke signature");
4344 header
= cfg
->header
;
4345 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4346 clause
= &header
->clauses
[i
];
4347 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
)
4348 LLVM_FAILURE (ctx
, "non-finally/catch clause.");
4351 if (linfo
->rgctx_arg
) {
4352 ctx
->rgctx_arg
= LLVMGetParam (method
, sinfo
.rgctx_arg_pindex
);
4354 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4355 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4356 * CC_X86_64_Mono in X86CallingConv.td.
4358 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
4359 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
4361 if (cfg
->vret_addr
) {
4362 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, sinfo
.vret_arg_pindex
);
4363 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
4366 values
[cfg
->args
[0]->dreg
] = LLVMGetParam (method
, sinfo
.this_arg_pindex
);
4367 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
4370 names
= g_new (char *, sig
->param_count
);
4371 mono_method_get_param_names (cfg
->method
, (const char **) names
);
4373 for (i
= 0; i
< sig
->param_count
; ++i
) {
4376 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, sinfo
.pindexes
[i
]);
4377 if (names
[i
] && names
[i
][0] != '\0')
4378 name
= g_strdup_printf ("arg_%s", names
[i
]);
4380 name
= g_strdup_printf ("arg_%d", i
);
4381 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
4383 if (linfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
)
4384 LLVMAddAttribute (LLVMGetParam (method
, sinfo
.pindexes
[i
]), LLVMByValAttribute
);
4389 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
4390 max_block_num
= MAX (max_block_num
, bb
->block_num
);
4391 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
4393 /* Add branches between non-consecutive bblocks */
4394 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4395 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
4396 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
4398 MonoInst
*inst
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
4399 inst
->opcode
= OP_BR
;
4400 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
4401 mono_bblock_add_inst (bb
, inst
);
4406 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4407 * was later optimized away, so clear these flags, and add them back for the still
4408 * present OP_LDADDR instructions.
4410 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
4413 ins
= get_vreg_to_inst (cfg
, i
);
4414 if (ins
&& ins
!= cfg
->rgctx_var
)
4415 ins
->flags
&= ~MONO_INST_INDIRECT
;
4419 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4421 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4423 LLVMBuilderRef builder
;
4425 char dname_buf
[128];
4427 builder
= create_builder (ctx
);
4429 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4430 switch (ins
->opcode
) {
4435 LLVMTypeRef phi_type
= llvm_type_to_stack_type (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
4437 CHECK_FAILURE (ctx
);
4439 if (ins
->opcode
== OP_VPHI
) {
4440 /* Treat valuetype PHI nodes as operating on the address itself */
4441 g_assert (ins
->klass
);
4442 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
4446 * Have to precreate these, as they can be referenced by
4447 * earlier instructions.
4449 sprintf (dname_buf
, "t%d", ins
->dreg
);
4451 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
4453 if (ins
->opcode
== OP_VPHI
)
4454 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
4456 g_ptr_array_add (phi_values
, values
[ins
->dreg
]);
4459 * Set the expected type of the incoming arguments since these have
4460 * to have the same type.
4462 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4463 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4466 ctx
->vreg_types
[sreg1
] = phi_type
;
4471 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
4480 * Create an ordering for bblocks, use the depth first order first, then
4481 * put the exception handling bblocks last.
4483 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
4484 bb
= cfg
->bblocks
[bb_index
];
4485 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
4486 g_ptr_array_add (bblock_list
, bb
);
4487 bblocks
[bb
->block_num
].added
= TRUE
;
4491 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4492 if (!bblocks
[bb
->block_num
].added
)
4493 g_ptr_array_add (bblock_list
, bb
);
4497 * Second pass: generate code.
4499 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
4500 bb
= g_ptr_array_index (bblock_list
, bb_index
);
4502 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4505 process_bb (ctx
, bb
);
4506 CHECK_FAILURE (ctx
);
4509 /* Add incoming phi values */
4510 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4511 GSList
*l
, *ins_list
;
4513 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
4515 for (l
= ins_list
; l
; l
= l
->next
) {
4516 PhiNode
*node
= l
->data
;
4517 MonoInst
*phi
= node
->phi
;
4518 int sreg1
= node
->sreg
;
4519 LLVMBasicBlockRef in_bb
;
4524 in_bb
= get_end_bb (ctx
, node
->in_bb
);
4526 if (ctx
->unreachable
[node
->in_bb
->block_num
])
4529 g_assert (values
[sreg1
]);
4531 if (phi
->opcode
== OP_VPHI
) {
4532 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4533 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
4535 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4536 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
4541 /* Create the SWITCH statements for ENDFINALLY instructions */
4542 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4543 BBInfo
*info
= &bblocks
[bb
->block_num
];
4545 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
4546 LLVMValueRef switch_ins
= l
->data
;
4547 GSList
*bb_list
= info
->call_handler_return_bbs
;
4549 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
4550 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), g_slist_nth (bb_list
, i
)->data
);
4554 if (cfg
->verbose_level
> 1)
4555 mono_llvm_dump_value (method
);
4557 mark_as_used (module
, method
);
4559 if (cfg
->compile_aot
) {
4560 /* Don't generate native code, keep the LLVM IR */
4561 if (cfg
->compile_aot
&& cfg
->verbose_level
)
4562 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), method_name
);
4564 //LLVMVerifyFunction(method, 0);
4566 mono_llvm_optimize_method (method
);
4568 if (cfg
->verbose_level
> 1)
4569 mono_llvm_dump_value (method
);
4571 cfg
->native_code
= LLVMGetPointerToGlobal (ee
, method
);
4573 /* Set by emit_cb */
4574 g_assert (cfg
->code_len
);
4576 /* FIXME: Free the LLVM IL for the function */
4584 /* Need to add unused phi nodes as they can be referenced by other values */
4585 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (method
, "PHI_BB");
4586 LLVMBuilderRef builder
;
4588 builder
= create_builder (ctx
);
4589 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
4591 for (i
= 0; i
< phi_values
->len
; ++i
) {
4592 LLVMValueRef v
= g_ptr_array_index (phi_values
, i
);
4593 if (LLVMGetInstructionParent (v
) == NULL
)
4594 LLVMInsertIntoBuilder (builder
, v
);
4597 LLVMDeleteFunction (method
);
4602 g_free (ctx
->addresses
);
4603 g_free (ctx
->vreg_types
);
4604 g_free (ctx
->vreg_cli_types
);
4605 g_free (ctx
->pindexes
);
4606 g_free (ctx
->is_dead
);
4607 g_free (ctx
->unreachable
);
4608 g_ptr_array_free (phi_values
, TRUE
);
4609 g_free (ctx
->bblocks
);
4610 g_hash_table_destroy (ctx
->region_to_handler
);
4611 g_free (method_name
);
4612 g_ptr_array_free (bblock_list
, TRUE
);
4614 for (l
= ctx
->builders
; l
; l
= l
->next
) {
4615 LLVMBuilderRef builder
= l
->data
;
4616 LLVMDisposeBuilder (builder
);
4621 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
4623 mono_loader_unlock ();
4627 * mono_llvm_emit_call:
4629 * Same as mono_arch_emit_call () for LLVM.
4632 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
4635 MonoMethodSignature
*sig
;
4636 int i
, n
, stack_size
;
4641 sig
= call
->signature
;
4642 n
= sig
->param_count
+ sig
->hasthis
;
4644 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4646 if (cfg
->disable_llvm
)
4649 if (sig
->call_convention
== MONO_CALL_VARARG
) {
4650 cfg
->exception_message
= g_strdup ("varargs");
4651 cfg
->disable_llvm
= TRUE
;
4654 for (i
= 0; i
< n
; ++i
) {
4657 ainfo
= call
->cinfo
->args
+ i
;
4659 in
= call
->args
[i
];
4661 /* Simply remember the arguments */
4662 switch (ainfo
->storage
) {
4664 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
4665 ins
->dreg
= mono_alloc_ireg (cfg
);
4666 ins
->sreg1
= in
->dreg
;
4668 case LLVMArgInFPReg
:
4669 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
4670 ins
->dreg
= mono_alloc_freg (cfg
);
4671 ins
->sreg1
= in
->dreg
;
4673 case LLVMArgVtypeByVal
:
4674 case LLVMArgVtypeInReg
:
4675 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
4676 ins
->dreg
= mono_alloc_ireg (cfg
);
4677 ins
->sreg1
= in
->dreg
;
4678 ins
->klass
= mono_class_from_mono_type (sig
->params
[i
- sig
->hasthis
]);
4681 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4682 cfg
->exception_message
= g_strdup ("ainfo->storage");
4683 cfg
->disable_llvm
= TRUE
;
4687 if (!cfg
->disable_llvm
) {
4688 MONO_ADD_INS (cfg
->cbb
, ins
);
4689 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
4694 static unsigned char*
4695 alloc_cb (LLVMValueRef function
, int size
)
4699 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4703 return mono_domain_code_reserve (cfg
->domain
, size
);
4705 return mono_domain_code_reserve (mono_domain_get (), size
);
4710 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
4714 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4716 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
4720 exception_cb (void *data
)
4723 MonoJitExceptionInfo
*ei
;
4724 guint32 ei_len
, i
, j
, nested_len
, nindex
;
4725 gpointer
*type_info
;
4726 int this_reg
, this_offset
;
4728 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4732 * data points to a DWARF FDE structure, convert it to our unwind format and
4734 * An alternative would be to save it directly, and modify our unwinder to work
4737 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
);
4739 /* Count nested clauses */
4741 for (i
= 0; i
< ei_len
; ++i
) {
4742 for (j
= 0; j
< ei_len
; ++j
) {
4743 gint32 cindex1
= *(gint32
*)type_info
[i
];
4744 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4745 gint32 cindex2
= *(gint32
*)type_info
[j
];
4746 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4748 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4754 cfg
->llvm_ex_info
= mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
4755 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
4756 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
4757 /* Fill the rest of the information from the type info */
4758 for (i
= 0; i
< ei_len
; ++i
) {
4759 gint32 clause_index
= *(gint32
*)type_info
[i
];
4760 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
4762 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
4763 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
4767 * For nested clauses, the LLVM produced exception info associates the try interval with
4768 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4770 /* FIXME: These should be order with the normal clauses */
4772 for (i
= 0; i
< ei_len
; ++i
) {
4773 for (j
= 0; j
< ei_len
; ++j
) {
4774 gint32 cindex1
= *(gint32
*)type_info
[i
];
4775 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4776 gint32 cindex2
= *(gint32
*)type_info
[j
];
4777 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4779 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4781 * The try interval comes from the nested clause, everything else from the
4784 memcpy (&cfg
->llvm_ex_info
[nindex
], &cfg
->llvm_ex_info
[j
], sizeof (MonoJitExceptionInfo
));
4785 cfg
->llvm_ex_info
[nindex
].try_start
= cfg
->llvm_ex_info
[i
].try_start
;
4786 cfg
->llvm_ex_info
[nindex
].try_end
= cfg
->llvm_ex_info
[i
].try_end
;
4791 g_assert (nindex
== ei_len
+ nested_len
);
4792 cfg
->llvm_this_reg
= this_reg
;
4793 cfg
->llvm_this_offset
= this_offset
;
4795 /* type_info [i] is cfg mempool allocated, no need to free it */
4802 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
4804 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
4808 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
4810 LLVMTypeRef param_types
[4];
4812 param_types
[0] = param_type1
;
4813 param_types
[1] = param_type2
;
4815 AddFunc (module
, name
, ret_type
, param_types
, 2);
4819 add_intrinsics (LLVMModuleRef module
)
4821 /* Emit declarations of instrinsics */
4823 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4824 * type doesn't seem to do any locking.
4827 LLVMTypeRef memset_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4829 memset_param_count
= 5;
4830 memset_func_name
= "llvm.memset.p0i8.i32";
4832 LLVMAddFunction (module
, memset_func_name
, LLVMFunctionType (LLVMVoidType (), memset_params
, memset_param_count
, FALSE
));
4836 LLVMTypeRef memcpy_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4838 memcpy_param_count
= 5;
4839 memcpy_func_name
= "llvm.memcpy.p0i8.p0i8.i32";
4841 LLVMAddFunction (module
, memcpy_func_name
, LLVMFunctionType (LLVMVoidType (), memcpy_params
, memcpy_param_count
, FALSE
));
4845 LLVMTypeRef params
[] = { LLVMDoubleType () };
4847 LLVMAddFunction (module
, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4848 LLVMAddFunction (module
, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4849 LLVMAddFunction (module
, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4851 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4852 LLVMAddFunction (module
, "fabs", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4856 LLVMTypeRef membar_params
[] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
4858 LLVMAddFunction (module
, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
4859 LLVMAddFunction (module
, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
4860 LLVMAddFunction (module
, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
4861 LLVMAddFunction (module
, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
4862 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE
));
4863 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE
));
4864 LLVMAddFunction (module
, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params
, 5, FALSE
));
4868 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
4869 LLVMTypeRef ovf_params_i32
[] = { LLVMInt32Type (), LLVMInt32Type () };
4871 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4872 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4873 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4874 LLVMAddFunction (module
, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4875 LLVMAddFunction (module
, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4876 LLVMAddFunction (module
, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4880 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
4881 LLVMTypeRef ovf_params_i64
[] = { LLVMInt64Type (), LLVMInt64Type () };
4883 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4884 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4885 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4886 LLVMAddFunction (module
, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4887 LLVMAddFunction (module
, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4888 LLVMAddFunction (module
, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4892 LLVMTypeRef struct_ptr
= LLVMPointerType (LLVMStructType (NULL
, 0, FALSE
), 0);
4893 LLVMTypeRef invariant_start_params
[] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4894 LLVMTypeRef invariant_end_params
[] = { struct_ptr
, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4896 LLVMAddFunction (module
, "llvm.invariant.start", LLVMFunctionType (struct_ptr
, invariant_start_params
, 2, FALSE
));
4898 LLVMAddFunction (module
, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params
, 3, FALSE
));
4903 LLVMTypeRef arg_types
[2];
4904 LLVMTypeRef ret_type
;
4906 arg_types
[0] = LLVMPointerType (LLVMInt8Type (), 0);
4907 arg_types
[1] = LLVMPointerType (LLVMInt8Type (), 0);
4908 eh_selector_name
= "llvm.eh.selector";
4909 ret_type
= LLVMInt32Type ();
4911 LLVMAddFunction (module
, eh_selector_name
, LLVMFunctionType (ret_type
, arg_types
, 2, TRUE
));
4913 LLVMAddFunction (module
, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL
, 0, FALSE
));
4915 LLVMAddFunction (module
, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4917 LLVMAddFunction (module
, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4920 /* SSE intrinsics */
4922 LLVMTypeRef ret_type
, arg_types
[2];
4925 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4926 arg_types
[0] = ret_type
;
4927 arg_types
[1] = ret_type
;
4928 AddFunc (module
, "llvm.x86.sse41.pminud", ret_type
, arg_types
, 2);
4929 AddFunc (module
, "llvm.x86.sse41.pmaxud", ret_type
, arg_types
, 2);
4930 AddFunc (module
, "llvm.x86.sse2.pcmpeq.d", ret_type
, arg_types
, 2);
4932 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4933 arg_types
[0] = ret_type
;
4934 arg_types
[1] = ret_type
;
4935 AddFunc (module
, "llvm.x86.sse41.pminuw", ret_type
, arg_types
, 2);
4936 AddFunc (module
, "llvm.x86.sse2.pmins.w", ret_type
, arg_types
, 2);
4937 AddFunc (module
, "llvm.x86.sse41.pmaxuw", ret_type
, arg_types
, 2);
4938 AddFunc (module
, "llvm.x86.sse2.pcmpeq.w", ret_type
, arg_types
, 2);
4939 AddFunc (module
, "llvm.x86.sse2.padds.w", ret_type
, arg_types
, 2);
4940 AddFunc (module
, "llvm.x86.sse2.psubs.w", ret_type
, arg_types
, 2);
4941 AddFunc (module
, "llvm.x86.sse2.paddus.w", ret_type
, arg_types
, 2);
4942 AddFunc (module
, "llvm.x86.sse2.psubus.w", ret_type
, arg_types
, 2);
4943 AddFunc (module
, "llvm.x86.sse2.pavg.w", ret_type
, arg_types
, 2);
4944 AddFunc (module
, "llvm.x86.sse2.pmulh.w", ret_type
, arg_types
, 2);
4945 AddFunc (module
, "llvm.x86.sse2.pmulhu.w", ret_type
, arg_types
, 2);
4947 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4948 arg_types
[0] = ret_type
;
4949 arg_types
[1] = ret_type
;
4950 AddFunc (module
, "llvm.x86.sse2.pminu.b", ret_type
, arg_types
, 2);
4951 AddFunc (module
, "llvm.x86.sse2.pmaxu.b", ret_type
, arg_types
, 2);
4952 AddFunc (module
, "llvm.x86.sse2.pcmpeq.b", ret_type
, arg_types
, 2);
4953 AddFunc (module
, "llvm.x86.sse2.pcmpgt.b", ret_type
, arg_types
, 2);
4954 AddFunc (module
, "llvm.x86.sse2.padds.b", ret_type
, arg_types
, 2);
4955 AddFunc (module
, "llvm.x86.sse2.psubs.b", ret_type
, arg_types
, 2);
4956 AddFunc (module
, "llvm.x86.sse2.paddus.b", ret_type
, arg_types
, 2);
4957 AddFunc (module
, "llvm.x86.sse2.psubus.b", ret_type
, arg_types
, 2);
4958 AddFunc (module
, "llvm.x86.sse2.pavg.b", ret_type
, arg_types
, 2);
4960 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
4961 arg_types
[0] = ret_type
;
4962 arg_types
[1] = ret_type
;
4963 AddFunc (module
, "llvm.x86.sse41.pcmpeqq", ret_type
, arg_types
, 2);
4965 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4966 arg_types
[0] = ret_type
;
4967 arg_types
[1] = ret_type
;
4968 AddFunc (module
, "llvm.x86.sse2.min.pd", ret_type
, arg_types
, 2);
4969 AddFunc (module
, "llvm.x86.sse2.max.pd", ret_type
, arg_types
, 2);
4970 AddFunc (module
, "llvm.x86.sse3.hadd.pd", ret_type
, arg_types
, 2);
4971 AddFunc (module
, "llvm.x86.sse3.hsub.pd", ret_type
, arg_types
, 2);
4972 AddFunc (module
, "llvm.x86.sse3.addsub.pd", ret_type
, arg_types
, 2);
4974 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4975 arg_types
[0] = ret_type
;
4976 arg_types
[1] = ret_type
;
4977 AddFunc (module
, "llvm.x86.sse.min.ps", ret_type
, arg_types
, 2);
4978 AddFunc (module
, "llvm.x86.sse.max.ps", ret_type
, arg_types
, 2);
4979 AddFunc (module
, "llvm.x86.sse3.hadd.ps", ret_type
, arg_types
, 2);
4980 AddFunc (module
, "llvm.x86.sse3.hsub.ps", ret_type
, arg_types
, 2);
4981 AddFunc (module
, "llvm.x86.sse3.addsub.ps", ret_type
, arg_types
, 2);
4984 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4985 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
4986 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
4987 AddFunc (module
, "llvm.x86.sse2.packsswb.128", ret_type
, arg_types
, 2);
4988 AddFunc (module
, "llvm.x86.sse2.packuswb.128", ret_type
, arg_types
, 2);
4989 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4990 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
4991 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
4992 AddFunc (module
, "llvm.x86.sse2.packssdw.128", ret_type
, arg_types
, 2);
4993 AddFunc (module
, "llvm.x86.sse41.packusdw", ret_type
, arg_types
, 2);
4996 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4997 arg_types
[0] = ret_type
;
4998 arg_types
[1] = ret_type
;
4999 arg_types
[2] = LLVMInt8Type ();
5000 AddFunc (module
, "llvm.x86.sse2.cmp.pd", ret_type
, arg_types
, 3);
5001 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5002 arg_types
[0] = ret_type
;
5003 arg_types
[1] = ret_type
;
5004 arg_types
[2] = LLVMInt8Type ();
5005 AddFunc (module
, "llvm.x86.sse.cmp.ps", ret_type
, arg_types
, 3);
5007 /* Conversion ops */
5008 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
5009 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
5010 AddFunc (module
, "llvm.x86.sse2.cvtdq2pd", ret_type
, arg_types
, 1);
5011 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5012 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
5013 AddFunc (module
, "llvm.x86.sse2.cvtdq2ps", ret_type
, arg_types
, 1);
5014 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5015 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5016 AddFunc (module
, "llvm.x86.sse2.cvtpd2dq", ret_type
, arg_types
, 1);
5017 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5018 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5019 AddFunc (module
, "llvm.x86.sse2.cvtps2dq", ret_type
, arg_types
, 1);
5020 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5021 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5022 AddFunc (module
, "llvm.x86.sse2.cvtpd2ps", ret_type
, arg_types
, 1);
5023 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
5024 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5025 AddFunc (module
, "llvm.x86.sse2.cvtps2pd", ret_type
, arg_types
, 1);
5027 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5028 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5029 AddFunc (module
, "llvm.x86.sse2.cvttpd2dq", ret_type
, arg_types
, 1);
5030 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5031 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5032 AddFunc (module
, "llvm.x86.sse2.cvttps2dq", ret_type
, arg_types
, 1);
5035 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
5036 arg_types
[0] = ret_type
;
5037 AddFunc (module
, "llvm.x86.sse2.sqrt.pd", ret_type
, arg_types
, 1);
5038 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5039 arg_types
[0] = ret_type
;
5040 AddFunc (module
, "llvm.x86.sse.sqrt.ps", ret_type
, arg_types
, 1);
5041 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5042 arg_types
[0] = ret_type
;
5043 AddFunc (module
, "llvm.x86.sse.rsqrt.ps", ret_type
, arg_types
, 1);
5044 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5045 arg_types
[0] = ret_type
;
5046 AddFunc (module
, "llvm.x86.sse.rcp.ps", ret_type
, arg_types
, 1);
5049 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
5050 arg_types
[0] = ret_type
;
5051 arg_types
[1] = LLVMInt32Type ();
5052 AddFunc (module
, "llvm.x86.sse2.psrli.w", ret_type
, arg_types
, 2);
5053 AddFunc (module
, "llvm.x86.sse2.psrai.w", ret_type
, arg_types
, 2);
5054 AddFunc (module
, "llvm.x86.sse2.pslli.w", ret_type
, arg_types
, 2);
5055 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5056 arg_types
[0] = ret_type
;
5057 arg_types
[1] = LLVMInt32Type ();
5058 AddFunc (module
, "llvm.x86.sse2.psrli.d", ret_type
, arg_types
, 2);
5059 AddFunc (module
, "llvm.x86.sse2.psrai.d", ret_type
, arg_types
, 2);
5060 AddFunc (module
, "llvm.x86.sse2.pslli.d", ret_type
, arg_types
, 2);
5061 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
5062 arg_types
[0] = ret_type
;
5063 arg_types
[1] = LLVMInt32Type ();
5064 AddFunc (module
, "llvm.x86.sse2.psrli.q", ret_type
, arg_types
, 2);
5065 AddFunc (module
, "llvm.x86.sse2.pslli.q", ret_type
, arg_types
, 2);
5068 ret_type
= LLVMInt32Type ();
5069 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
5070 AddFunc (module
, "llvm.x86.sse2.pmovmskb.128", ret_type
, arg_types
, 1);
5073 if (IS_LLVM_MONO_BRANCH
) {
5074 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
5077 /* Load/Store intrinsics */
5078 if (IS_LLVM_MONO_BRANCH
) {
5079 LLVMTypeRef arg_types
[5];
5083 for (i
= 1; i
<= 8; i
*= 2) {
5084 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5085 arg_types
[1] = LLVMInt32Type ();
5086 arg_types
[2] = LLVMInt1Type ();
5087 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
5088 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMIntType (i
* 8), arg_types
, 3, FALSE
));
5090 arg_types
[0] = LLVMIntType (i
* 8);
5091 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5092 arg_types
[2] = LLVMInt32Type ();
5093 arg_types
[3] = LLVMInt1Type ();
5094 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
5095 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMVoidType (), arg_types
, 4, FALSE
));
5101 mono_llvm_init (void)
5103 mono_native_tls_alloc (current_cfg_tls_id
, NULL
);
5107 init_jit_module (void)
5109 MonoJitICallInfo
*info
;
5111 if (jit_module_inited
)
5114 mono_loader_lock ();
5116 if (jit_module_inited
) {
5117 mono_loader_unlock ();
5121 jit_module
.module
= LLVMModuleCreateWithName ("mono");
5123 ee
= mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module
.module
), alloc_cb
, emitted_cb
, exception_cb
);
5125 add_intrinsics (jit_module
.module
);
5127 jit_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5129 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5131 LLVMAddGlobalMapping (ee
, LLVMGetNamedFunction (jit_module
.module
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
5133 jit_module_inited
= TRUE
;
5135 mono_loader_unlock ();
5139 mono_llvm_cleanup (void)
5142 mono_llvm_dispose_ee (ee
);
5144 if (jit_module
.llvm_types
)
5145 g_hash_table_destroy (jit_module
.llvm_types
);
5147 if (aot_module
.module
)
5148 LLVMDisposeModule (aot_module
.module
);
5150 LLVMContextDispose (LLVMGetGlobalContext ());
5154 mono_llvm_create_aot_module (const char *got_symbol
)
5156 /* Delete previous module */
5157 if (aot_module
.plt_entries
)
5158 g_hash_table_destroy (aot_module
.plt_entries
);
5159 if (aot_module
.module
)
5160 LLVMDisposeModule (aot_module
.module
);
5162 memset (&aot_module
, 0, sizeof (aot_module
));
5164 aot_module
.module
= LLVMModuleCreateWithName ("aot");
5165 aot_module
.got_symbol
= got_symbol
;
5167 add_intrinsics (aot_module
.module
);
5171 * We couldn't compute the type of the LLVM global representing the got because
5172 * its size is only known after all the methods have been emitted. So create
5173 * a dummy variable, and replace all uses it with the real got variable when
5174 * its size is known in mono_llvm_emit_aot_module ().
5177 LLVMTypeRef got_type
= LLVMArrayType (IntPtrType (), 0);
5179 aot_module
.got_var
= LLVMAddGlobal (aot_module
.module
, got_type
, "mono_dummy_got");
5180 LLVMSetInitializer (aot_module
.got_var
, LLVMConstNull (got_type
));
5183 /* Add a dummy personality function */
5185 LLVMBasicBlockRef lbb
;
5186 LLVMBuilderRef lbuilder
;
5187 LLVMValueRef personality
;
5189 personality
= LLVMAddFunction (aot_module
.module
, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
5190 LLVMSetLinkage (personality
, LLVMPrivateLinkage
);
5191 lbb
= LLVMAppendBasicBlock (personality
, "BB0");
5192 lbuilder
= LLVMCreateBuilder ();
5193 LLVMPositionBuilderAtEnd (lbuilder
, lbb
);
5194 LLVMBuildRetVoid (lbuilder
);
5197 aot_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5198 aot_module
.plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
5202 * Emit the aot module into the LLVM bitcode file FILENAME.
5205 mono_llvm_emit_aot_module (const char *filename
, int got_size
)
5207 LLVMTypeRef got_type
;
5208 LLVMValueRef real_got
;
5211 * Create the real got variable and replace all uses of the dummy variable with
5214 got_type
= LLVMArrayType (IntPtrType (), got_size
);
5215 real_got
= LLVMAddGlobal (aot_module
.module
, got_type
, aot_module
.got_symbol
);
5216 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
5217 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
5219 mono_llvm_replace_uses_of (aot_module
.got_var
, real_got
);
5221 mark_as_used (aot_module
.module
, real_got
);
5223 /* Delete the dummy got so it doesn't become a global */
5224 LLVMDeleteGlobal (aot_module
.got_var
);
5230 if (LLVMVerifyModule (aot_module
.module
, LLVMReturnStatusAction
, &verifier_err
)) {
5231 g_assert_not_reached ();
5236 LLVMWriteBitcodeToFile (aot_module
.module
, filename
);
5241 - Emit LLVM IR from the mono IR using the LLVM C API.
5242 - The original arch specific code remains, so we can fall back to it if we run
5243 into something we can't handle.
5247 A partial list of issues:
5248 - Handling of opcodes which can throw exceptions.
5250 In the mono JIT, these are implemented using code like this:
5257 push throw_pos - method
5258 call <exception trampoline>
5260 The problematic part is push throw_pos - method, which cannot be represented
5261 in the LLVM IR, since it does not support label values.
5262 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5263 be implemented in JIT mode ?
5264 -> a possible but slower implementation would use the normal exception
5265 throwing code but it would need to control the placement of the throw code
5266 (it needs to be exactly after the compare+branch).
5267 -> perhaps add a PC offset intrinsics ?
5269 - efficient implementation of .ovf opcodes.
5271 These are currently implemented as:
5272 <ins which sets the condition codes>
5275 Some overflow opcodes are now supported by LLVM SVN.
5277 - exception handling, unwinding.
5278 - SSA is disabled for methods with exception handlers
5279 - How to obtain unwind info for LLVM compiled methods ?
5280 -> this is now solved by converting the unwind info generated by LLVM
5282 - LLVM uses the c++ exception handling framework, while we use our home grown
5283 code, and couldn't use the c++ one:
5284 - its not supported under VC++, other exotic platforms.
5285 - it might be impossible to support filter clauses with it.
5289 The trampolines need a predictable call sequence, since they need to disasm
5290 the calling code to obtain register numbers / offsets.
5292 LLVM currently generates this code in non-JIT mode:
5293 mov -0x98(%rax),%eax
5295 Here, the vtable pointer is lost.
5296 -> solution: use one vtable trampoline per class.
5298 - passing/receiving the IMT pointer/RGCTX.
5299 -> solution: pass them as normal arguments ?
5303 LLVM does not allow the specification of argument registers etc. This means
5304 that all calls are made according to the platform ABI.
5306 - passing/receiving vtypes.
5308 Vtypes passed/received in registers are handled by the front end by using
5309 a signature with scalar arguments, and loading the parts of the vtype into those
5312 Vtypes passed on the stack are handled using the 'byval' attribute.
5316 Supported though alloca, we need to emit the load/store code.
5320 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5321 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5322 This is made easier because the IR is already in SSA form.
5323 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5324 types are frequently used incorrectly.
5329 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5330 append the AOT data structures to that file. For methods which cannot be
5331 handled by LLVM, the normal JIT compiled versions are used.
5334 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5335 * - each bblock should end with a branch
5336 * - setting the return value, making cfg->ret non-volatile
5337 * - avoid some transformations in the JIT which make it harder for us to generate
5339 * - use pointer types to help optimizations.