2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
33 LLVMValueRef
throw, rethrow
, throw_corlib_exception
;
34 GHashTable
*llvm_types
;
36 const char *got_symbol
;
37 GHashTable
*plt_entries
;
41 * Information associated by the backend with mono basic blocks.
44 LLVMBasicBlockRef bblock
, end_bblock
;
45 LLVMValueRef finally_ind
;
46 gboolean added
, invoke_target
;
48 * If this bblock is the start of a finally clause, this is a list of bblocks it
49 * needs to branch to in ENDFINALLY.
51 GSList
*call_handler_return_bbs
;
53 * If this bblock is the start of a finally clause, this is the bblock that
54 * CALL_HANDLER needs to branch to.
56 LLVMBasicBlockRef call_handler_target_bb
;
57 /* The list of switch statements generated by ENDFINALLY instructions */
58 GSList
*endfinally_switch_ins_list
;
63 * Structure containing emit state
68 /* Maps method names to the corresponding LLVMValueRef */
69 GHashTable
*emitted_method_decls
;
73 MonoLLVMModule
*lmodule
;
76 int sindex
, default_index
, ex_index
;
77 LLVMBuilderRef builder
;
78 LLVMValueRef
*values
, *addresses
;
79 MonoType
**vreg_cli_types
;
81 MonoMethodSignature
*sig
;
83 GHashTable
*region_to_handler
;
84 LLVMBuilderRef alloca_builder
;
85 LLVMValueRef last_alloca
;
86 LLVMValueRef rgctx_arg
;
87 LLVMTypeRef
*vreg_types
;
89 gboolean
*unreachable
;
98 MonoBasicBlock
*in_bb
;
103 * Instruction metadata
104 * This is the same as ins_info, but LREG != IREG.
112 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
113 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
120 /* keep in sync with the enum in mini.h */
123 #include "mini-ops.h"
128 #if SIZEOF_VOID_P == 4
129 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
131 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
134 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
137 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
139 #define TRACE_FAILURE(msg)
143 #define IS_TARGET_X86 1
145 #define IS_TARGET_X86 0
148 #define LLVM_FAILURE(ctx, reason) do { \
149 TRACE_FAILURE (reason); \
150 (ctx)->cfg->exception_message = g_strdup (reason); \
151 (ctx)->cfg->disable_llvm = TRUE; \
155 #define CHECK_FAILURE(ctx) do { \
156 if ((ctx)->cfg->disable_llvm) \
160 static LLVMIntPredicate cond_to_llvm_cond
[] = {
173 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
186 static LLVMExecutionEngineRef ee
;
187 static MonoNativeTlsKey current_cfg_tls_id
;
189 static MonoLLVMModule jit_module
, aot_module
;
190 static gboolean jit_module_inited
;
191 static int memset_param_count
, memcpy_param_count
;
192 static const char *memset_func_name
;
193 static const char *memcpy_func_name
;
195 static void init_jit_module (void);
200 * The LLVM type with width == sizeof (gpointer)
205 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
211 * Return the size of the LLVM representation of the vtype T.
214 get_vtype_size (MonoType
*t
)
218 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
220 while (size
< sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
227 * simd_class_to_llvm_type:
229 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
232 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
234 if (!strcmp (klass
->name
, "Vector2d")) {
235 return LLVMVectorType (LLVMDoubleType (), 2);
236 } else if (!strcmp (klass
->name
, "Vector2l")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass
->name
, "Vector2ul")) {
239 return LLVMVectorType (LLVMInt64Type (), 2);
240 } else if (!strcmp (klass
->name
, "Vector4i")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass
->name
, "Vector4ui")) {
243 return LLVMVectorType (LLVMInt32Type (), 4);
244 } else if (!strcmp (klass
->name
, "Vector4f")) {
245 return LLVMVectorType (LLVMFloatType (), 4);
246 } else if (!strcmp (klass
->name
, "Vector8s")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass
->name
, "Vector8us")) {
249 return LLVMVectorType (LLVMInt16Type (), 8);
250 } else if (!strcmp (klass
->name
, "Vector16sb")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else if (!strcmp (klass
->name
, "Vector16b")) {
253 return LLVMVectorType (LLVMInt8Type (), 16);
255 printf ("%s\n", klass
->name
);
261 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
262 static inline G_GNUC_UNUSED LLVMTypeRef
263 type_to_simd_type (int type
)
267 return LLVMVectorType (LLVMInt8Type (), 16);
269 return LLVMVectorType (LLVMInt16Type (), 8);
271 return LLVMVectorType (LLVMInt32Type (), 4);
273 return LLVMVectorType (LLVMInt64Type (), 2);
275 return LLVMVectorType (LLVMDoubleType (), 2);
277 return LLVMVectorType (LLVMFloatType (), 4);
279 g_assert_not_reached ();
287 * Return the LLVM type corresponding to T.
290 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
293 return LLVMPointerType (LLVMInt8Type (), 0);
296 return LLVMVoidType ();
298 return LLVMInt8Type ();
300 return LLVMInt16Type ();
302 return LLVMInt32Type ();
304 return LLVMInt8Type ();
306 return LLVMInt16Type ();
308 return LLVMInt32Type ();
309 case MONO_TYPE_BOOLEAN
:
310 return LLVMInt8Type ();
313 return LLVMInt64Type ();
315 return LLVMInt16Type ();
317 return LLVMFloatType ();
319 return LLVMDoubleType ();
322 return IntPtrType ();
323 case MONO_TYPE_OBJECT
:
324 case MONO_TYPE_CLASS
:
325 case MONO_TYPE_ARRAY
:
326 case MONO_TYPE_SZARRAY
:
327 case MONO_TYPE_STRING
:
329 return IntPtrType ();
332 /* Because of generic sharing */
333 if (mini_type_var_is_vt (ctx
->cfg
, t
))
334 return type_to_llvm_type (ctx
, mini_get_gsharedvt_alloc_type_for_type (ctx
->cfg
, t
));
336 return IntPtrType ();
337 case MONO_TYPE_GENERICINST
:
338 if (!mono_type_generic_inst_is_valuetype (t
))
339 return IntPtrType ();
341 case MONO_TYPE_VALUETYPE
:
342 case MONO_TYPE_TYPEDBYREF
: {
346 klass
= mono_class_from_mono_type (t
);
348 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
349 return simd_class_to_llvm_type (ctx
, klass
);
352 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
353 ltype
= g_hash_table_lookup (ctx
->lmodule
->llvm_types
, klass
);
356 LLVMTypeRef
*eltypes
;
359 size
= get_vtype_size (t
);
361 eltypes
= g_new (LLVMTypeRef
, size
);
362 for (i
= 0; i
< size
; ++i
)
363 eltypes
[i
] = LLVMInt8Type ();
365 name
= mono_type_full_name (&klass
->byval_arg
);
366 ltype
= LLVMStructCreateNamed (LLVMGetGlobalContext (), name
);
367 LLVMStructSetBody (ltype
, eltypes
, size
, FALSE
);
368 g_hash_table_insert (ctx
->lmodule
->llvm_types
, klass
, ltype
);
375 printf ("X: %d\n", t
->type
);
376 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
377 ctx
->cfg
->disable_llvm
= TRUE
;
385 * Return whenever T is an unsigned int type.
388 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
404 * type_to_llvm_arg_type:
406 * Same as type_to_llvm_type, but treat i8/i16 as i32.
409 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
411 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
413 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
415 * LLVM generates code which only sets the lower bits, while JITted
416 * code expects all the bits to be set.
418 ptype
= LLVMInt32Type ();
425 * llvm_type_to_stack_type:
427 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
430 static G_GNUC_UNUSED LLVMTypeRef
431 llvm_type_to_stack_type (LLVMTypeRef type
)
435 if (type
== LLVMInt8Type ())
436 return LLVMInt32Type ();
437 else if (type
== LLVMInt16Type ())
438 return LLVMInt32Type ();
439 else if (type
== LLVMFloatType ())
440 return LLVMDoubleType ();
446 * regtype_to_llvm_type:
448 * Return the LLVM type corresponding to the regtype C used in instruction
452 regtype_to_llvm_type (char c
)
456 return LLVMInt32Type ();
458 return LLVMInt64Type ();
460 return LLVMDoubleType ();
469 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
472 op_to_llvm_type (int opcode
)
477 return LLVMInt8Type ();
480 return LLVMInt8Type ();
483 return LLVMInt16Type ();
486 return LLVMInt16Type ();
489 return LLVMInt32Type ();
492 return LLVMInt32Type ();
494 return LLVMInt64Type ();
496 return LLVMFloatType ();
498 return LLVMDoubleType ();
500 return LLVMInt64Type ();
502 return LLVMInt32Type ();
504 return LLVMInt64Type ();
507 return LLVMInt8Type ();
510 return LLVMInt16Type ();
513 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
520 return LLVMInt32Type ();
527 return LLVMInt64Type ();
529 printf ("%s\n", mono_inst_name (opcode
));
530 g_assert_not_reached ();
536 * load_store_to_llvm_type:
538 * Return the size/sign/zero extension corresponding to the load/store opcode
542 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
548 case OP_LOADI1_MEMBASE
:
549 case OP_STOREI1_MEMBASE_REG
:
550 case OP_STOREI1_MEMBASE_IMM
:
553 return LLVMInt8Type ();
554 case OP_LOADU1_MEMBASE
:
558 return LLVMInt8Type ();
559 case OP_LOADI2_MEMBASE
:
560 case OP_STOREI2_MEMBASE_REG
:
561 case OP_STOREI2_MEMBASE_IMM
:
564 return LLVMInt16Type ();
565 case OP_LOADU2_MEMBASE
:
569 return LLVMInt16Type ();
570 case OP_LOADI4_MEMBASE
:
571 case OP_LOADU4_MEMBASE
:
574 case OP_STOREI4_MEMBASE_REG
:
575 case OP_STOREI4_MEMBASE_IMM
:
577 return LLVMInt32Type ();
578 case OP_LOADI8_MEMBASE
:
580 case OP_STOREI8_MEMBASE_REG
:
581 case OP_STOREI8_MEMBASE_IMM
:
583 return LLVMInt64Type ();
584 case OP_LOADR4_MEMBASE
:
585 case OP_STORER4_MEMBASE_REG
:
587 return LLVMFloatType ();
588 case OP_LOADR8_MEMBASE
:
589 case OP_STORER8_MEMBASE_REG
:
591 return LLVMDoubleType ();
592 case OP_LOAD_MEMBASE
:
594 case OP_STORE_MEMBASE_REG
:
595 case OP_STORE_MEMBASE_IMM
:
596 *size
= sizeof (gpointer
);
597 return IntPtrType ();
599 g_assert_not_reached ();
607 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
610 ovf_op_to_intrins (int opcode
)
614 return "llvm.sadd.with.overflow.i32";
616 return "llvm.uadd.with.overflow.i32";
618 return "llvm.ssub.with.overflow.i32";
620 return "llvm.usub.with.overflow.i32";
622 return "llvm.smul.with.overflow.i32";
624 return "llvm.umul.with.overflow.i32";
626 return "llvm.sadd.with.overflow.i64";
628 return "llvm.uadd.with.overflow.i64";
630 return "llvm.ssub.with.overflow.i64";
632 return "llvm.usub.with.overflow.i64";
634 return "llvm.smul.with.overflow.i64";
636 return "llvm.umul.with.overflow.i64";
638 g_assert_not_reached ();
644 simd_op_to_intrins (int opcode
)
647 #if defined(TARGET_X86) || defined(TARGET_AMD64)
649 return "llvm.x86.sse2.min.pd";
651 return "llvm.x86.sse.min.ps";
653 return "llvm.x86.sse41.pminud";
655 return "llvm.x86.sse41.pminuw";
657 return "llvm.x86.sse2.pminu.b";
659 return "llvm.x86.sse2.pmins.w";
661 return "llvm.x86.sse2.max.pd";
663 return "llvm.x86.sse.max.ps";
665 return "llvm.x86.sse3.hadd.pd";
667 return "llvm.x86.sse3.hadd.ps";
669 return "llvm.x86.sse3.hsub.pd";
671 return "llvm.x86.sse3.hsub.ps";
673 return "llvm.x86.sse41.pmaxud";
675 return "llvm.x86.sse41.pmaxuw";
677 return "llvm.x86.sse2.pmaxu.b";
679 return "llvm.x86.sse3.addsub.ps";
681 return "llvm.x86.sse3.addsub.pd";
682 case OP_EXTRACT_MASK
:
683 return "llvm.x86.sse2.pmovmskb.128";
686 return "llvm.x86.sse2.psrli.w";
689 return "llvm.x86.sse2.psrli.d";
692 return "llvm.x86.sse2.psrli.q";
695 return "llvm.x86.sse2.pslli.w";
698 return "llvm.x86.sse2.pslli.d";
701 return "llvm.x86.sse2.pslli.q";
704 return "llvm.x86.sse2.psrai.w";
707 return "llvm.x86.sse2.psrai.d";
709 return "llvm.x86.sse2.padds.b";
711 return "llvm.x86.sse2.padds.w";
713 return "llvm.x86.sse2.psubs.b";
715 return "llvm.x86.sse2.psubs.w";
716 case OP_PADDB_SAT_UN
:
717 return "llvm.x86.sse2.paddus.b";
718 case OP_PADDW_SAT_UN
:
719 return "llvm.x86.sse2.paddus.w";
720 case OP_PSUBB_SAT_UN
:
721 return "llvm.x86.sse2.psubus.b";
722 case OP_PSUBW_SAT_UN
:
723 return "llvm.x86.sse2.psubus.w";
725 return "llvm.x86.sse2.pavg.b";
727 return "llvm.x86.sse2.pavg.w";
729 return "llvm.x86.sse.sqrt.ps";
731 return "llvm.x86.sse2.sqrt.pd";
733 return "llvm.x86.sse.rsqrt.ps";
735 return "llvm.x86.sse.rcp.ps";
737 return "llvm.x86.sse2.cvtdq2pd";
739 return "llvm.x86.sse2.cvtdq2ps";
741 return "llvm.x86.sse2.cvtpd2dq";
743 return "llvm.x86.sse2.cvtps2dq";
745 return "llvm.x86.sse2.cvtpd2ps";
747 return "llvm.x86.sse2.cvtps2pd";
749 return "llvm.x86.sse2.cvttpd2dq";
751 return "llvm.x86.sse2.cvttps2dq";
753 return "llvm.x86.sse.cmp.ps";
755 return "llvm.x86.sse2.cmp.pd";
757 return "llvm.x86.sse2.packsswb.128";
759 return "llvm.x86.sse2.packssdw.128";
761 return "llvm.x86.sse2.packuswb.128";
763 return "llvm.x86.sse41.packusdw";
765 return "llvm.x86.sse2.pmulh.w";
766 case OP_PMULW_HIGH_UN
:
767 return "llvm.x86.sse2.pmulhu.w";
770 g_assert_not_reached ();
776 simd_op_to_llvm_type (int opcode
)
778 #if defined(TARGET_X86) || defined(TARGET_AMD64)
782 return type_to_simd_type (MONO_TYPE_R8
);
785 return type_to_simd_type (MONO_TYPE_I8
);
788 return type_to_simd_type (MONO_TYPE_I4
);
793 return type_to_simd_type (MONO_TYPE_I2
);
797 return type_to_simd_type (MONO_TYPE_I1
);
799 return type_to_simd_type (MONO_TYPE_R4
);
802 return type_to_simd_type (MONO_TYPE_I4
);
806 return type_to_simd_type (MONO_TYPE_R8
);
810 return type_to_simd_type (MONO_TYPE_R4
);
811 case OP_EXTRACT_MASK
:
812 return type_to_simd_type (MONO_TYPE_I1
);
818 return type_to_simd_type (MONO_TYPE_R4
);
821 return type_to_simd_type (MONO_TYPE_R8
);
823 g_assert_not_reached ();
834 * Return the LLVM basic block corresponding to BB.
836 static LLVMBasicBlockRef
837 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
841 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
842 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
843 int clause_index
= (mono_get_block_region_notry (ctx
->cfg
, bb
->region
) >> 8) - 1;
844 sprintf (bb_name
, "EH_CLAUSE%d_BB%d", clause_index
, bb
->block_num
);
846 sprintf (bb_name
, "BB%d", bb
->block_num
);
849 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
850 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
853 return ctx
->bblocks
[bb
->block_num
].bblock
;
859 * Return the last LLVM bblock corresponding to BB.
860 * This might not be equal to the bb returned by get_bb () since we need to generate
861 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
863 static LLVMBasicBlockRef
864 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
867 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
870 static LLVMBasicBlockRef
871 gen_bb (EmitContext
*ctx
, const char *prefix
)
875 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
876 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
882 * Return the target of the patch identified by TYPE and TARGET.
885 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
889 memset (&ji
, 0, sizeof (ji
));
891 ji
.data
.target
= target
;
893 return mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
);
899 * Emit code to convert the LLVM value V to DTYPE.
902 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
904 LLVMTypeRef stype
= LLVMTypeOf (v
);
906 if (stype
!= dtype
) {
907 gboolean ext
= FALSE
;
910 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
912 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
914 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
918 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
920 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
921 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
924 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
925 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
926 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
927 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
928 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
929 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
930 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
931 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
933 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
934 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
935 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
936 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
937 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
938 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
940 #ifdef MONO_ARCH_SOFT_FLOAT
941 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
942 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
943 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
944 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
947 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
948 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
951 LLVMDumpValue (LLVMConstNull (dtype
));
952 g_assert_not_reached ();
960 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
962 return convert_full (ctx
, v
, dtype
, FALSE
);
966 * emit_volatile_load:
968 * If vreg is volatile, emit a load from its address.
971 emit_volatile_load (EmitContext
*ctx
, int vreg
)
975 LLVMValueRef v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
976 t
= ctx
->vreg_cli_types
[vreg
];
977 if (t
&& !t
->byref
) {
979 * Might have to zero extend since llvm doesn't have
982 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
983 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
984 else if (t
->type
== MONO_TYPE_U8
)
985 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
992 * emit_volatile_store:
994 * If VREG is volatile, emit a store from its value to its address.
997 emit_volatile_store (EmitContext
*ctx
, int vreg
)
999 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1001 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1002 g_assert (ctx
->addresses
[vreg
]);
1003 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1009 * Maps parameter indexes in the original signature to parameter indexes
1010 * in the LLVM signature.
1013 /* The indexes of various special arguments in the LLVM signature */
1014 int vret_arg_pindex
, this_arg_pindex
, rgctx_arg_pindex
, imt_arg_pindex
;
1018 * sig_to_llvm_sig_full:
1020 * Return the LLVM signature corresponding to the mono signature SIG using the
1021 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1024 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
,
1027 LLVMTypeRef ret_type
;
1028 LLVMTypeRef
*param_types
= NULL
;
1030 int i
, j
, pindex
, vret_arg_pindex
= 0;
1032 gboolean vretaddr
= FALSE
;
1035 memset (sinfo
, 0, sizeof (LLVMSigInfo
));
1037 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1038 CHECK_FAILURE (ctx
);
1040 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
1041 /* LLVM models this by returning an aggregate value */
1042 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1043 LLVMTypeRef members
[2];
1045 members
[0] = IntPtrType ();
1046 ret_type
= LLVMStructType (members
, 1, FALSE
);
1048 g_assert_not_reached ();
1050 } else if (cinfo
&& mini_type_is_vtype (ctx
->cfg
, sig
->ret
)) {
1051 g_assert (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
);
1053 ret_type
= LLVMVoidType ();
1056 pindexes
= g_new0 (int, sig
->param_count
);
1057 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 2) + 3);
1059 if (cinfo
&& cinfo
->rgctx_arg
) {
1061 sinfo
->rgctx_arg_pindex
= pindex
;
1062 param_types
[pindex
] = IntPtrType ();
1065 if (cinfo
&& cinfo
->imt_arg
) {
1067 sinfo
->imt_arg_pindex
= pindex
;
1068 param_types
[pindex
] = IntPtrType ();
1072 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1073 vret_arg_pindex
= pindex
;
1074 if (cinfo
->vret_arg_index
== 1) {
1075 /* Add the slots consumed by the first argument */
1076 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1077 switch (ainfo
->storage
) {
1078 case LLVMArgVtypeInReg
:
1079 for (j
= 0; j
< 2; ++j
) {
1080 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1090 sinfo
->vret_arg_pindex
= vret_arg_pindex
;
1093 if (vretaddr
&& vret_arg_pindex
== pindex
)
1094 param_types
[pindex
++] = IntPtrType ();
1097 sinfo
->this_arg_pindex
= pindex
;
1098 param_types
[pindex
++] = IntPtrType ();
1100 if (vretaddr
&& vret_arg_pindex
== pindex
)
1101 param_types
[pindex
++] = IntPtrType ();
1102 for (i
= 0; i
< sig
->param_count
; ++i
) {
1103 if (vretaddr
&& vret_arg_pindex
== pindex
)
1104 param_types
[pindex
++] = IntPtrType ();
1105 pindexes
[i
] = pindex
;
1106 if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeInReg
) {
1107 for (j
= 0; j
< 2; ++j
) {
1108 switch (cinfo
->args
[i
+ sig
->hasthis
].pair_storage
[j
]) {
1110 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
1115 g_assert_not_reached ();
1118 } else if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
) {
1119 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1120 CHECK_FAILURE (ctx
);
1121 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1124 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1127 if (vretaddr
&& vret_arg_pindex
== pindex
)
1128 param_types
[pindex
++] = IntPtrType ();
1130 CHECK_FAILURE (ctx
);
1132 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1133 g_free (param_types
);
1136 sinfo
->pindexes
= pindexes
;
1144 g_free (param_types
);
1150 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1152 return sig_to_llvm_sig_full (ctx
, sig
, NULL
, NULL
);
1156 * LLVMFunctionType1:
1158 * Create an LLVM function type from the arguments.
1160 static G_GNUC_UNUSED LLVMTypeRef
1161 LLVMFunctionType1(LLVMTypeRef ReturnType
,
1162 LLVMTypeRef ParamType1
,
1165 LLVMTypeRef param_types
[1];
1167 param_types
[0] = ParamType1
;
1169 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1173 * LLVMFunctionType2:
1175 * Create an LLVM function type from the arguments.
1177 static G_GNUC_UNUSED LLVMTypeRef
1178 LLVMFunctionType2(LLVMTypeRef ReturnType
,
1179 LLVMTypeRef ParamType1
,
1180 LLVMTypeRef ParamType2
,
1183 LLVMTypeRef param_types
[2];
1185 param_types
[0] = ParamType1
;
1186 param_types
[1] = ParamType2
;
1188 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1192 * LLVMFunctionType3:
1194 * Create an LLVM function type from the arguments.
1196 static G_GNUC_UNUSED LLVMTypeRef
1197 LLVMFunctionType3(LLVMTypeRef ReturnType
,
1198 LLVMTypeRef ParamType1
,
1199 LLVMTypeRef ParamType2
,
1200 LLVMTypeRef ParamType3
,
1203 LLVMTypeRef param_types
[3];
1205 param_types
[0] = ParamType1
;
1206 param_types
[1] = ParamType2
;
1207 param_types
[2] = ParamType3
;
1209 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1215 * Create an LLVM builder and remember it so it can be freed later.
1217 static LLVMBuilderRef
1218 create_builder (EmitContext
*ctx
)
1220 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1222 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1228 get_plt_entry (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1230 char *callee_name
= mono_aot_get_plt_symbol (type
, data
);
1231 LLVMValueRef callee
;
1236 if (ctx
->cfg
->compile_aot
)
1237 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1238 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1241 callee
= g_hash_table_lookup (ctx
->lmodule
->plt_entries
, callee_name
);
1243 callee
= LLVMAddFunction (ctx
->module
, callee_name
, llvm_sig
);
1245 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1247 g_hash_table_insert (ctx
->lmodule
->plt_entries
, (char*)callee_name
, callee
);
1254 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1256 MonoMethodHeader
*header
= cfg
->header
;
1257 MonoExceptionClause
*clause
;
1261 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1262 return (bb
->region
>> 8) - 1;
1265 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1266 clause
= &header
->clauses
[i
];
1268 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1276 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1278 LLVMValueRef md_arg
;
1281 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1282 md_arg
= LLVMMDString ("mono", 4);
1283 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1289 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1293 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1295 MonoCompile
*cfg
= ctx
->cfg
;
1297 LLVMBuilderRef builder
= *builder_ref
;
1300 clause_index
= get_handler_clause (cfg
, bb
);
1302 if (clause_index
!= -1) {
1303 MonoMethodHeader
*header
= cfg
->header
;
1304 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1305 MonoBasicBlock
*tblock
;
1306 LLVMBasicBlockRef ex_bb
, noex_bb
;
1309 * Have to use an invoke instead of a call, branching to the
1310 * handler bblock of the clause containing this bblock.
1313 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1315 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1318 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1320 ex_bb
= get_bb (ctx
, tblock
);
1322 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1325 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1327 builder
= ctx
->builder
= create_builder (ctx
);
1328 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1330 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1332 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1333 ctx
->builder
= builder
;
1336 *builder_ref
= ctx
->builder
;
1342 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
1344 const char *intrins_name
;
1345 LLVMValueRef args
[16], res
;
1346 LLVMTypeRef addr_type
;
1348 if (is_faulting
&& bb
->region
!= -1) {
1350 * We handle loads which can fault by calling a mono specific intrinsic
1351 * using an invoke, so they are handled properly inside try blocks.
1352 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1353 * are marked with IntrReadArgMem.
1357 intrins_name
= "llvm.mono.load.i8.p0i8";
1360 intrins_name
= "llvm.mono.load.i16.p0i16";
1363 intrins_name
= "llvm.mono.load.i32.p0i32";
1366 intrins_name
= "llvm.mono.load.i64.p0i64";
1369 g_assert_not_reached ();
1372 addr_type
= LLVMTypeOf (addr
);
1373 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1374 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1377 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1378 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1379 res
= emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 3);
1381 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1382 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1383 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1384 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1391 * We emit volatile loads for loads which can fault, because otherwise
1392 * LLVM will generate invalid code when encountering a load from a
1395 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1397 /* Mark it with a custom metadata */
1400 set_metadata_flag (res, "mono.faulting.load");
1408 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, gboolean is_faulting
)
1410 const char *intrins_name
;
1411 LLVMValueRef args
[16];
1413 if (is_faulting
&& bb
->region
!= -1) {
1416 intrins_name
= "llvm.mono.store.i8.p0i8";
1419 intrins_name
= "llvm.mono.store.i16.p0i16";
1422 intrins_name
= "llvm.mono.store.i32.p0i32";
1425 intrins_name
= "llvm.mono.store.i64.p0i64";
1428 g_assert_not_reached ();
1431 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
1432 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
1433 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1438 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1439 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1440 emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 4);
1442 LLVMBuildStore (*builder_ref
, value
, addr
);
1447 * emit_cond_system_exception:
1449 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1450 * Might set the ctx exception.
1453 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
1455 LLVMBasicBlockRef ex_bb
, noex_bb
;
1456 LLVMBuilderRef builder
;
1457 MonoClass
*exc_class
;
1458 LLVMValueRef args
[2];
1460 ex_bb
= gen_bb (ctx
, "EX_BB");
1461 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1463 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
1465 exc_class
= mono_class_from_name (mono_get_corlib (), "System", exc_type
);
1466 g_assert (exc_class
);
1468 /* Emit exception throwing code */
1469 builder
= create_builder (ctx
);
1470 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
1472 if (!ctx
->lmodule
->throw_corlib_exception
) {
1473 LLVMValueRef callee
;
1475 const char *icall_name
;
1477 MonoMethodSignature
*throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 2);
1478 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
1479 throw_sig
->params
[0] = &mono_get_int32_class ()->byval_arg
;
1480 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
1481 throw_sig
->params
[1] = &mono_get_intptr_class ()->byval_arg
;
1482 sig
= sig_to_llvm_sig (ctx
, throw_sig
);
1484 if (ctx
->cfg
->compile_aot
) {
1485 callee
= get_plt_entry (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
1487 callee
= LLVMAddFunction (ctx
->module
, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx
, throw_sig
));
1490 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1491 * - On x86, LLVM generated code doesn't push the arguments
1492 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1493 * arguments, not a pc offset.
1495 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
1498 mono_memory_barrier ();
1499 ctx
->lmodule
->throw_corlib_exception
= callee
;
1503 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
1505 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
, FALSE
);
1508 * The LLVM mono branch contains changes so a block address can be passed as an
1509 * argument to a call.
1511 args
[1] = LLVMBuildPtrToInt (builder
, LLVMBlockAddress (ctx
->lmethod
, ex_bb
), IntPtrType (), "");
1512 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1514 LLVMBuildUnreachable (builder
);
1516 ctx
->builder
= create_builder (ctx
);
1517 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1519 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1526 * emit_reg_to_vtype:
1528 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1531 emit_reg_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
)
1535 size
= get_vtype_size (t
);
1537 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1538 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1541 for (j
= 0; j
< 2; ++j
) {
1542 LLVMValueRef index
[2], addr
;
1543 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1544 LLVMTypeRef part_type
;
1546 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1549 part_type
= LLVMIntType (part_size
* 8);
1550 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1551 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1552 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1554 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1555 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1556 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1558 switch (ainfo
->pair_storage
[j
]) {
1560 LLVMBuildStore (builder
, convert (ctx
, regs
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
1565 g_assert_not_reached ();
1568 size
-= sizeof (gpointer
);
1573 * emit_vtype_to_reg:
1575 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1576 * into REGS, and the number of registers into NREGS.
1579 emit_vtype_to_reg (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
, guint32
*nregs
)
1584 size
= get_vtype_size (t
);
1586 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1587 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1590 for (j
= 0; j
< 2; ++j
) {
1591 LLVMValueRef index
[2], addr
;
1592 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1594 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1597 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1598 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1599 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1601 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1602 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1603 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1605 switch (ainfo
->pair_storage
[j
]) {
1607 regs
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
1612 g_assert_not_reached ();
1614 size
-= sizeof (gpointer
);
1621 build_alloca (EmitContext
*ctx
, MonoType
*t
)
1623 MonoClass
*k
= mono_class_from_mono_type (t
);
1626 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
1629 align
= mono_class_min_align (k
);
1631 /* Sometimes align is not a power of 2 */
1632 while (mono_is_power_of_two (align
) == -1)
1636 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1637 * get executed every time control reaches them.
1639 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
1641 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, type_to_llvm_type (ctx
, t
), NULL
, align
, "");
1642 return ctx
->last_alloca
;
1646 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1649 mark_as_used (LLVMModuleRef module
, LLVMValueRef global
)
1651 LLVMTypeRef used_type
;
1652 LLVMValueRef used
, used_elem
;
1654 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1655 used
= LLVMAddGlobal (module
, used_type
, "llvm.used");
1656 used_elem
= LLVMConstBitCast (global
, LLVMPointerType (LLVMInt8Type (), 0));
1657 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem
, 1));
1658 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
1659 LLVMSetSection (used
, "llvm.metadata");
1665 * Emit code to load/convert arguments.
1668 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
1671 MonoCompile
*cfg
= ctx
->cfg
;
1672 MonoMethodSignature
*sig
= ctx
->sig
;
1673 LLVMCallInfo
*linfo
= ctx
->linfo
;
1676 ctx
->alloca_builder
= create_builder (ctx
);
1679 * Handle indirect/volatile variables by allocating memory for them
1680 * using 'alloca', and storing their address in a temporary.
1682 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
1683 MonoInst
*var
= cfg
->varinfo
[i
];
1686 if (var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) || mini_type_is_vtype (cfg
, var
->inst_vtype
)) {
1687 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
1688 CHECK_FAILURE (ctx
);
1689 /* Could be already created by an OP_VPHI */
1690 if (!ctx
->addresses
[var
->dreg
])
1691 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
1692 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
1696 for (i
= 0; i
< sig
->param_count
; ++i
) {
1697 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
1698 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
1700 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
1701 LLVMValueRef regs
[2];
1704 * Emit code to save the argument from the registers to
1705 * the real argument.
1707 pindex
= ctx
->pindexes
[i
];
1708 regs
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
1709 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
1710 regs
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
1714 ctx
->addresses
[reg
] = build_alloca (ctx
, sig
->params
[i
]);
1716 emit_reg_to_vtype (ctx
, builder
, sig
->params
[i
], ctx
->addresses
[reg
], ainfo
, regs
);
1718 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1719 /* Treat these as normal values */
1720 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1722 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
1723 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, ctx
->pindexes
[i
]);
1725 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1726 /* Treat these as normal values */
1727 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1730 ctx
->values
[reg
] = convert (ctx
, ctx
->values
[reg
], llvm_type_to_stack_type (type_to_llvm_type (ctx
, sig
->params
[i
])));
1735 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
1737 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
1738 for (i
= 0; i
< sig
->param_count
; ++i
)
1739 if (!mini_type_is_vtype (cfg
, sig
->params
[i
]))
1740 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
1742 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->generic_sharing_context
) {
1743 LLVMValueRef this_alloc
;
1746 * The exception handling code needs the location where the this argument was
1747 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1748 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1749 * location into the LSDA.
1751 this_alloc
= mono_llvm_build_alloca (builder
, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
1752 /* This volatile store will keep the alloca alive */
1753 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
);
1755 set_metadata_flag (this_alloc
, "mono.this");
1758 if (cfg
->rgctx_var
) {
1759 LLVMValueRef rgctx_alloc
, store
;
1762 * We handle the rgctx arg similarly to the this pointer.
1764 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
1765 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
1766 /* This volatile store will keep the alloca alive */
1767 store
= mono_llvm_build_store (builder
, ctx
->rgctx_arg
, rgctx_alloc
, TRUE
);
1769 set_metadata_flag (rgctx_alloc
, "mono.this");
1773 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1774 * it needs to continue normally, or return back to the exception handling system.
1776 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1777 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
))
1778 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
1779 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
) && bb
->in_scount
== 0) {
1783 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
1784 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
1785 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
1787 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
1790 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1791 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1792 * LLVM optimizer passes.
1794 sprintf (name
, "BB_%d_CALL_HANDLER_TARGET", bb
->block_num
);
1795 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
1803 /* Have to export this for AOT */
1805 mono_personality (void);
1808 mono_personality (void)
1811 g_assert_not_reached ();
1815 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
1817 MonoCompile
*cfg
= ctx
->cfg
;
1818 LLVMModuleRef module
= ctx
->module
;
1819 LLVMValueRef
*values
= ctx
->values
;
1820 LLVMValueRef
*addresses
= ctx
->addresses
;
1821 MonoCallInst
*call
= (MonoCallInst
*)ins
;
1822 MonoMethodSignature
*sig
= call
->signature
;
1823 LLVMValueRef callee
= NULL
, lcall
;
1825 LLVMCallInfo
*cinfo
;
1829 LLVMTypeRef llvm_sig
;
1831 gboolean
virtual, calli
;
1832 LLVMBuilderRef builder
= *builder_ref
;
1835 if (call
->signature
->call_convention
!= MONO_CALL_DEFAULT
)
1836 LLVM_FAILURE (ctx
, "non-default callconv");
1838 cinfo
= call
->cinfo
;
1839 if (call
->rgctx_arg_reg
)
1840 cinfo
->rgctx_arg
= TRUE
;
1841 if (call
->imt_arg_reg
)
1842 cinfo
->imt_arg
= TRUE
;
1844 vretaddr
= cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
;
1846 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
, &sinfo
);
1847 CHECK_FAILURE (ctx
);
1849 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
);
1850 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
);
1852 /* FIXME: Avoid creating duplicate methods */
1854 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
1858 if (cfg
->compile_aot
) {
1859 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
1861 LLVM_FAILURE (ctx
, "can't encode patch");
1863 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1866 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1868 LLVMAddGlobalMapping (ee
, callee
, target
);
1873 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
1879 memset (&ji, 0, sizeof (ji));
1880 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1881 ji.data.target = info->name;
1883 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1885 if (cfg
->compile_aot
) {
1886 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
1888 LLVM_FAILURE (ctx
, "can't encode patch");
1890 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1891 target
= (gpointer
)mono_icall_get_wrapper (info
);
1892 LLVMAddGlobalMapping (ee
, callee
, target
);
1895 if (cfg
->compile_aot
) {
1897 if (cfg
->abs_patches
) {
1898 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1900 callee
= get_plt_entry (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
1902 LLVM_FAILURE (ctx
, "can't encode patch");
1906 LLVM_FAILURE (ctx
, "aot");
1908 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1910 if (cfg
->abs_patches
) {
1911 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1914 * FIXME: Some trampolines might have
1915 * their own calling convention on some platforms.
1917 #ifndef TARGET_AMD64
1918 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
)
1919 LLVM_FAILURE (ctx
, "trampoline with own cconv");
1921 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
);
1922 LLVMAddGlobalMapping (ee
, callee
, target
);
1926 LLVMAddGlobalMapping (ee
, callee
, (gpointer
)call
->fptr
);
1932 int size
= sizeof (gpointer
);
1935 g_assert (ins
->inst_offset
% size
== 0);
1936 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
1938 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
1940 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
1942 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
1947 * Collect and convert arguments
1949 nargs
= (sig
->param_count
* 2) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
;
1950 len
= sizeof (LLVMValueRef
) * nargs
;
1951 args
= alloca (len
);
1952 memset (args
, 0, len
);
1953 l
= call
->out_ireg_args
;
1955 if (call
->rgctx_arg_reg
) {
1956 g_assert (values
[call
->rgctx_arg_reg
]);
1957 g_assert (sinfo
.rgctx_arg_pindex
< nargs
);
1958 args
[sinfo
.rgctx_arg_pindex
] = values
[call
->rgctx_arg_reg
];
1960 if (call
->imt_arg_reg
) {
1961 g_assert (values
[call
->imt_arg_reg
]);
1962 g_assert (sinfo
.imt_arg_pindex
< nargs
);
1963 args
[sinfo
.imt_arg_pindex
] = values
[call
->imt_arg_reg
];
1967 if (!addresses
[call
->inst
.dreg
])
1968 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
1969 g_assert (sinfo
.vret_arg_pindex
< nargs
);
1970 args
[sinfo
.vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
1973 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
1976 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
] : NULL
;
1980 pindex
= sinfo
.this_arg_pindex
;
1982 pindex
= sinfo
.pindexes
[i
- 1];
1984 pindex
= sinfo
.pindexes
[i
];
1987 regpair
= (guint32
)(gssize
)(l
->data
);
1988 reg
= regpair
& 0xffffff;
1989 args
[pindex
] = values
[reg
];
1990 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
1992 LLVMValueRef regs
[2];
1997 g_assert (addresses
[reg
]);
1999 emit_vtype_to_reg (ctx
, builder
, sig
->params
[i
- sig
->hasthis
], addresses
[reg
], ainfo
, regs
, &nregs
);
2000 for (j
= 0; j
< nregs
; ++j
)
2001 args
[pindex
++] = regs
[j
];
2004 // FIXME: Get rid of the VMOVE
2005 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
2006 g_assert (addresses
[reg
]);
2007 args
[pindex
] = addresses
[reg
];
2009 g_assert (args
[pindex
]);
2010 if (i
== 0 && sig
->hasthis
)
2011 args
[pindex
] = convert (ctx
, args
[pindex
], IntPtrType ());
2013 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, sig
->params
[i
- sig
->hasthis
]));
2019 // FIXME: Align call sites
2025 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
2027 #ifdef LLVM_MONO_BRANCH
2029 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2031 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2032 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
2034 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2035 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
2037 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
2039 if (call
->rgctx_arg_reg
)
2040 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.rgctx_arg_pindex
, LLVMInRegAttribute
);
2041 if (call
->imt_arg_reg
)
2042 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.imt_arg_pindex
, LLVMInRegAttribute
);
2045 /* Add byval attributes if needed */
2046 for (i
= 0; i
< sig
->param_count
; ++i
) {
2047 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
+ sig
->hasthis
] : NULL
;
2049 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
) {
2050 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.pindexes
[i
], LLVMByValAttribute
);
2055 * Convert the result
2057 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2058 LLVMValueRef regs
[2];
2060 if (!addresses
[ins
->dreg
])
2061 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
2063 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
2064 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
2065 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
2067 emit_reg_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
2068 } else if (sig
->ret
->type
!= MONO_TYPE_VOID
&& !vretaddr
) {
2069 /* If the method returns an unsigned value, need to zext it */
2071 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
));
2074 *builder_ref
= ctx
->builder
;
2076 g_free (sinfo
.pindexes
);
2084 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
2086 MonoCompile
*cfg
= ctx
->cfg
;
2087 MonoMethodSignature
*sig
= ctx
->sig
;
2088 LLVMValueRef method
= ctx
->lmethod
;
2089 LLVMValueRef
*values
= ctx
->values
;
2090 LLVMValueRef
*addresses
= ctx
->addresses
;
2092 LLVMCallInfo
*linfo
= ctx
->linfo
;
2093 LLVMModuleRef module
= ctx
->module
;
2094 BBInfo
*bblocks
= ctx
->bblocks
;
2096 LLVMBasicBlockRef cbb
;
2097 LLVMBuilderRef builder
, starting_builder
;
2098 gboolean has_terminator
;
2100 LLVMValueRef lhs
, rhs
;
2103 cbb
= get_bb (ctx
, bb
);
2104 builder
= create_builder (ctx
);
2105 ctx
->builder
= builder
;
2106 LLVMPositionBuilderAtEnd (builder
, cbb
);
2108 if (bb
== cfg
->bb_entry
)
2109 emit_entry_bb (ctx
, builder
);
2110 CHECK_FAILURE (ctx
);
2112 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
2114 LLVMValueRef personality
;
2115 LLVMBasicBlockRef target_bb
;
2117 static gint32 mapping_inited
;
2118 static int ti_generator
;
2121 LLVMValueRef type_info
;
2124 if (!bblocks
[bb
->block_num
].invoke_target
) {
2126 * LLVM asserts if llvm.eh.selector is called from a bblock which
2127 * doesn't have an invoke pointing at it.
2128 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2130 LLVM_FAILURE (ctx
, "handler without invokes");
2133 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2135 if (cfg
->compile_aot
) {
2136 /* Use a dummy personality function */
2137 personality
= LLVMGetNamedFunction (module
, "mono_aot_personality");
2138 g_assert (personality
);
2140 personality
= LLVMGetNamedFunction (module
, "mono_personality");
2141 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
2142 LLVMAddGlobalMapping (ee
, personality
, mono_personality
);
2145 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
2147 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
2150 * Create the type info
2152 sprintf (ti_name
, "type_info_%d", ti_generator
);
2155 if (cfg
->compile_aot
) {
2156 /* decode_eh_frame () in aot-runtime.c will decode this */
2157 type_info
= LLVMAddGlobal (module
, LLVMInt32Type (), ti_name
);
2158 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
2160 LLVMSetLinkage (type_info
, LLVMPrivateLinkage
);
2161 LLVMSetVisibility (type_info
, LLVMHiddenVisibility
);
2164 * Enabling this causes llc to crash:
2165 * http://llvm.org/bugs/show_bug.cgi?id=6102
2167 //LLVM_FAILURE (ctx, "aot+clauses");
2169 // test_0_invalid_unbox_arrays () fails
2170 LLVM_FAILURE (ctx
, "aot+clauses");
2174 * After the cfg mempool is freed, the type info will point to stale memory,
2175 * but this is not a problem, since we decode it once in exception_cb during
2178 ti
= mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
2179 *(gint32
*)ti
= clause_index
;
2181 type_info
= LLVMAddGlobal (module
, i8ptr
, ti_name
);
2183 LLVMAddGlobalMapping (ee
, type_info
, ti
);
2187 LLVMTypeRef members
[2], ret_type
;
2188 LLVMValueRef landing_pad
;
2190 members
[0] = i8ptr
;
2191 members
[1] = LLVMInt32Type ();
2192 ret_type
= LLVMStructType (members
, 2, FALSE
);
2194 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
2195 LLVMAddClause (landing_pad
, type_info
);
2197 /* Store the exception into the exvar */
2198 if (bb
->in_scount
== 1) {
2199 g_assert (bb
->in_scount
== 1);
2200 exvar
= bb
->in_stack
[0];
2202 // FIXME: This is shared with filter clauses ?
2203 g_assert (!values
[exvar
->dreg
]);
2205 values
[exvar
->dreg
] = LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj");
2206 emit_volatile_store (ctx
, exvar
->dreg
);
2210 /* Start a new bblock which CALL_HANDLER can branch to */
2211 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
2213 LLVMBuildBr (builder
, target_bb
);
2215 ctx
->builder
= builder
= create_builder (ctx
);
2216 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
2218 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
2222 has_terminator
= FALSE
;
2223 starting_builder
= builder
;
2224 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
2225 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
2227 char dname_buf
[128];
2230 if (nins
> 5000 && builder
== starting_builder
) {
2231 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2232 LLVM_FAILURE (ctx
, "basic block too long");
2236 /* There could be instructions after a terminator, skip them */
2239 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
2240 sprintf (dname_buf
, "t%d", ins
->dreg
);
2244 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
2245 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
2247 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2248 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
2250 /* It is ok for SETRET to have an uninitialized argument */
2251 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
)
2252 LLVM_FAILURE (ctx
, "sreg1");
2253 lhs
= values
[ins
->sreg1
];
2259 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
2260 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
2261 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2262 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
2264 if (!values
[ins
->sreg2
])
2265 LLVM_FAILURE (ctx
, "sreg2");
2266 rhs
= values
[ins
->sreg2
];
2272 //mono_print_ins (ins);
2273 switch (ins
->opcode
) {
2276 case OP_LIVERANGE_START
:
2277 case OP_LIVERANGE_END
:
2280 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
2283 #if SIZEOF_VOID_P == 4
2284 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2286 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
2290 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
2293 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
2296 LLVMBuildBr (builder
, get_bb (ctx
, ins
->inst_target_bb
));
2297 has_terminator
= TRUE
;
2303 LLVMBasicBlockRef new_bb
;
2304 LLVMBuilderRef new_builder
;
2306 // The default branch is already handled
2307 // FIXME: Handle it here
2309 /* Start new bblock */
2310 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
2311 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
2313 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2314 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
2315 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
2316 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
2318 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
2321 new_builder
= create_builder (ctx
);
2322 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
2323 LLVMBuildUnreachable (new_builder
);
2325 has_terminator
= TRUE
;
2326 g_assert (!ins
->next
);
2332 if (linfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2333 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
2334 LLVMValueRef part1
, retval
;
2337 size
= get_vtype_size (sig
->ret
);
2339 g_assert (addresses
[ins
->sreg1
]);
2341 g_assert (linfo
->ret
.pair_storage
[0] == LLVMArgInIReg
);
2342 g_assert (linfo
->ret
.pair_storage
[1] == LLVMArgNone
);
2344 part1
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMIntType (size
* 8), 0), ""), ""), IntPtrType ());
2346 retval
= LLVMBuildInsertValue (builder
, LLVMGetUndef (ret_type
), part1
, 0, "");
2348 LLVMBuildRet (builder
, retval
);
2352 if (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
) {
2353 LLVMBuildRetVoid (builder
);
2357 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
2359 * The method did not set its return value, probably because it
2360 * ends with a throw.
2363 LLVMBuildRetVoid (builder
);
2365 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
2367 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
2369 has_terminator
= TRUE
;
2375 case OP_ICOMPARE_IMM
:
2376 case OP_LCOMPARE_IMM
:
2377 case OP_COMPARE_IMM
: {
2381 if (ins
->next
->opcode
== OP_NOP
)
2384 if (ins
->next
->opcode
== OP_BR
)
2385 /* The comparison result is not needed */
2388 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
2390 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
2391 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2392 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2394 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2395 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2396 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2398 if (ins
->opcode
== OP_LCOMPARE
) {
2399 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2400 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
2402 if (ins
->opcode
== OP_ICOMPARE
) {
2403 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2404 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2408 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2409 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
2410 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
2411 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
2414 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2415 if (ins
->opcode
== OP_FCOMPARE
)
2416 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2417 else if (ins
->opcode
== OP_COMPARE_IMM
)
2418 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
2419 else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2420 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
2421 /* The immediate is encoded in two fields */
2422 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
2423 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
2425 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
2428 else if (ins
->opcode
== OP_COMPARE
)
2429 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
2431 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
2433 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
2434 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
2436 * If the target bb contains PHI instructions, LLVM requires
2437 * two PHI entries for this bblock, while we only generate one.
2438 * So convert this to an unconditional bblock. (bxc #171).
2440 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
2442 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
2444 has_terminator
= TRUE
;
2445 } else if (MONO_IS_SETCC (ins
->next
)) {
2446 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
2448 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2450 /* Add stores for volatile variables */
2451 emit_volatile_store (ctx
, ins
->next
->dreg
);
2452 } else if (MONO_IS_COND_EXC (ins
->next
)) {
2453 emit_cond_system_exception (ctx
, bb
, ins
->next
->inst_p1
, cmp
);
2454 CHECK_FAILURE (ctx
);
2455 builder
= ctx
->builder
;
2457 LLVM_FAILURE (ctx
, "next");
2471 rel
= mono_opcode_to_cond (ins
->opcode
);
2473 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2474 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2482 gboolean empty
= TRUE
;
2484 /* Check that all input bblocks really branch to us */
2485 for (i
= 0; i
< bb
->in_count
; ++i
) {
2486 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
2487 ins
->inst_phi_args
[i
+ 1] = -1;
2493 /* LLVM doesn't like phi instructions with zero operands */
2494 ctx
->is_dead
[ins
->dreg
] = TRUE
;
2498 /* Created earlier, insert it now */
2499 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
2501 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
2502 int sreg1
= ins
->inst_phi_args
[i
+ 1];
2506 * Count the number of times the incoming bblock branches to us,
2507 * since llvm requires a separate entry for each.
2509 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
2510 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
2513 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
2514 if (switch_ins
->inst_many_bb
[j
] == bb
)
2521 /* Remember for later */
2522 for (j
= 0; j
< count
; ++j
) {
2523 PhiNode
*node
= mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
2526 node
->in_bb
= bb
->in_bb
[i
];
2528 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
);
2538 values
[ins
->dreg
] = lhs
;
2541 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
2544 values
[ins
->dreg
] = lhs
;
2546 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
2548 * This is added by the spilling pass in case of the JIT,
2549 * but we have to do it ourselves.
2551 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
2585 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2586 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2588 switch (ins
->opcode
) {
2591 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
2595 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
2599 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
2603 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
2607 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
2611 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
2615 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
2618 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
2622 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
2626 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
2630 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
2634 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
2638 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
2642 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
2646 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
2649 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
2652 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
2656 g_assert_not_reached ();
2663 case OP_IREM_UN_IMM
:
2665 case OP_IDIV_UN_IMM
:
2671 case OP_ISHR_UN_IMM
:
2680 case OP_LSHR_UN_IMM
:
2688 if (spec
[MONO_INST_SRC1
] == 'l') {
2689 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2691 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2694 #if SIZEOF_VOID_P == 4
2695 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
2696 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2699 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2700 lhs
= convert (ctx
, lhs
, IntPtrType ());
2701 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
2702 switch (ins
->opcode
) {
2706 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
2710 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
2714 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
2718 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
2720 case OP_IDIV_UN_IMM
:
2721 case OP_LDIV_UN_IMM
:
2722 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
2726 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
2728 case OP_IREM_UN_IMM
:
2729 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
2734 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
2738 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
2742 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
2747 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
2752 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
2754 case OP_ISHR_UN_IMM
:
2755 /* This is used to implement conv.u4, so the lhs could be an i8 */
2756 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2757 imm
= convert (ctx
, imm
, LLVMInt32Type ());
2758 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2760 case OP_LSHR_UN_IMM
:
2761 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2764 g_assert_not_reached ();
2769 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
2772 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
2775 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
2776 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
2779 guint32 v
= 0xffffffff;
2780 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
2784 guint64 v
= 0xffffffffffffffffLL
;
2785 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
2788 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2790 LLVMValueRef v1
, v2
;
2792 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
2793 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
2794 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
2799 case OP_ICONV_TO_I1
:
2800 case OP_ICONV_TO_I2
:
2801 case OP_ICONV_TO_I4
:
2802 case OP_ICONV_TO_U1
:
2803 case OP_ICONV_TO_U2
:
2804 case OP_ICONV_TO_U4
:
2805 case OP_LCONV_TO_I1
:
2806 case OP_LCONV_TO_I2
:
2807 case OP_LCONV_TO_U1
:
2808 case OP_LCONV_TO_U2
:
2809 case OP_LCONV_TO_U4
: {
2812 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
);
2814 /* Have to do two casts since our vregs have type int */
2815 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
2817 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
2819 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
2822 case OP_ICONV_TO_I8
:
2823 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2825 case OP_ICONV_TO_U8
:
2826 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2828 case OP_FCONV_TO_I4
:
2829 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
2831 case OP_FCONV_TO_I1
:
2832 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2834 case OP_FCONV_TO_U1
:
2835 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2837 case OP_FCONV_TO_I2
:
2838 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2840 case OP_FCONV_TO_U2
:
2841 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2843 case OP_FCONV_TO_I8
:
2844 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
2847 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
2849 case OP_ICONV_TO_R8
:
2850 case OP_LCONV_TO_R8
:
2851 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2853 case OP_LCONV_TO_R_UN
:
2854 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2856 #if SIZEOF_VOID_P == 4
2859 case OP_LCONV_TO_I4
:
2860 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2862 case OP_ICONV_TO_R4
:
2863 case OP_LCONV_TO_R4
:
2864 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
2865 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2867 case OP_FCONV_TO_R4
:
2868 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
2869 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2872 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2875 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2878 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2880 case OP_LOCALLOC_IMM
: {
2883 guint32 size
= ins
->inst_imm
;
2884 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
2886 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
2888 if (ins
->flags
& MONO_INST_INIT
) {
2889 LLVMValueRef args
[5];
2892 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2893 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
2894 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2895 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2896 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2899 values
[ins
->dreg
] = v
;
2903 LLVMValueRef v
, size
;
2905 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
), "");
2907 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
2909 if (ins
->flags
& MONO_INST_INIT
) {
2910 LLVMValueRef args
[5];
2913 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2915 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2916 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2917 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2919 values
[ins
->dreg
] = v
;
2923 case OP_LOADI1_MEMBASE
:
2924 case OP_LOADU1_MEMBASE
:
2925 case OP_LOADI2_MEMBASE
:
2926 case OP_LOADU2_MEMBASE
:
2927 case OP_LOADI4_MEMBASE
:
2928 case OP_LOADU4_MEMBASE
:
2929 case OP_LOADI8_MEMBASE
:
2930 case OP_LOADR4_MEMBASE
:
2931 case OP_LOADR8_MEMBASE
:
2932 case OP_LOAD_MEMBASE
:
2940 LLVMValueRef base
, index
, addr
;
2942 gboolean sext
= FALSE
, zext
= FALSE
;
2943 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
2945 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2950 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
)) {
2951 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
2956 if (ins
->inst_offset
== 0) {
2958 } else if (ins
->inst_offset
% size
!= 0) {
2959 /* Unaligned load */
2960 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2961 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
2963 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2964 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
2968 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
2970 values
[ins
->dreg
] = emit_load (ctx
, bb
, &builder
, size
, addr
, dname
, is_volatile
);
2972 if (!is_volatile
&& (ins
->flags
& MONO_INST_CONSTANT_LOAD
)) {
2974 * These will signal LLVM that these loads do not alias any stores, and
2975 * they can't fail, allowing them to be hoisted out of loops.
2977 set_metadata_flag (values
[ins
->dreg
], "mono.noalias");
2978 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
2982 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
2984 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
2985 else if (ins
->opcode
== OP_LOADR4_MEMBASE
)
2986 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
2990 case OP_STOREI1_MEMBASE_REG
:
2991 case OP_STOREI2_MEMBASE_REG
:
2992 case OP_STOREI4_MEMBASE_REG
:
2993 case OP_STOREI8_MEMBASE_REG
:
2994 case OP_STORER4_MEMBASE_REG
:
2995 case OP_STORER8_MEMBASE_REG
:
2996 case OP_STORE_MEMBASE_REG
: {
2998 LLVMValueRef index
, addr
;
3000 gboolean sext
= FALSE
, zext
= FALSE
;
3001 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3003 if (!values
[ins
->inst_destbasereg
])
3004 LLVM_FAILURE (ctx
, "inst_destbasereg");
3006 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3008 if (ins
->inst_offset
% size
!= 0) {
3009 /* Unaligned store */
3010 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3011 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3013 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3014 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3016 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), is_volatile
);
3020 case OP_STOREI1_MEMBASE_IMM
:
3021 case OP_STOREI2_MEMBASE_IMM
:
3022 case OP_STOREI4_MEMBASE_IMM
:
3023 case OP_STOREI8_MEMBASE_IMM
:
3024 case OP_STORE_MEMBASE_IMM
: {
3026 LLVMValueRef index
, addr
;
3028 gboolean sext
= FALSE
, zext
= FALSE
;
3029 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3031 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3033 if (ins
->inst_offset
% size
!= 0) {
3034 /* Unaligned store */
3035 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3036 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3038 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3039 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3041 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), addr
, is_volatile
);
3046 emit_load (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
3048 case OP_OUTARG_VTRETADDR
:
3055 case OP_VOIDCALL_MEMBASE
:
3056 case OP_CALL_MEMBASE
:
3057 case OP_LCALL_MEMBASE
:
3058 case OP_FCALL_MEMBASE
:
3059 case OP_VCALL_MEMBASE
:
3060 case OP_VOIDCALL_REG
:
3064 case OP_VCALL_REG
: {
3065 process_call (ctx
, bb
, &builder
, ins
);
3066 CHECK_FAILURE (ctx
);
3071 LLVMValueRef indexes
[2];
3073 LLVMValueRef got_entry_addr
;
3076 * FIXME: Can't allocate from the cfg mempool since that is freed if
3077 * the LLVM compile fails.
3079 ji
= g_new0 (MonoJumpInfo
, 1);
3080 ji
->type
= (MonoJumpInfoType
)ins
->inst_i1
;
3081 ji
->data
.target
= ins
->inst_p0
;
3083 ji
= mono_aot_patch_info_dup (ji
);
3085 ji
->next
= cfg
->patch_info
;
3086 cfg
->patch_info
= ji
;
3088 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3089 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
3091 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3092 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
3093 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->lmodule
->got_var
, indexes
, 2, "");
3095 // FIXME: This doesn't work right now, because it must be
3096 // paired with an invariant.end, and even then, its only in effect
3097 // inside its basic block
3100 LLVMValueRef args
[3];
3101 LLVMValueRef ptr
, val
;
3103 ptr
= LLVMBuildBitCast (builder
, got_entry_addr
, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3105 args
[0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer
), FALSE
);
3107 val
= LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.invariant.start"), args
, 2, "");
3111 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, dname
);
3114 case OP_NOT_REACHED
:
3115 LLVMBuildUnreachable (builder
);
3116 has_terminator
= TRUE
;
3117 g_assert (bb
->block_num
< cfg
->max_block_num
);
3118 ctx
->unreachable
[bb
->block_num
] = TRUE
;
3119 /* Might have instructions after this */
3121 MonoInst
*next
= ins
->next
;
3123 * FIXME: If later code uses the regs defined by these instructions,
3124 * compilation will fail.
3126 MONO_DELETE_INS (bb
, next
);
3130 MonoInst
*var
= ins
->inst_p0
;
3132 values
[ins
->dreg
] = addresses
[var
->dreg
];
3136 LLVMValueRef args
[1];
3138 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3139 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sin.f64"), args
, 1, dname
);
3143 LLVMValueRef args
[1];
3145 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3146 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.cos.f64"), args
, 1, dname
);
3150 LLVMValueRef args
[1];
3153 /* This no longer seems to happen */
3155 * LLVM optimizes sqrt(nan) into undefined in
3156 * lib/Analysis/ConstantFolding.cpp
3157 * Also, sqrt(NegativeInfinity) is optimized into 0.
3159 LLVM_FAILURE (ctx
, "sqrt");
3161 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3162 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sqrt.f64"), args
, 1, dname
);
3166 LLVMValueRef args
[1];
3168 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3169 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "fabs"), args
, 1, dname
);
3183 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3184 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3186 switch (ins
->opcode
) {
3189 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
3193 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
3197 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
3201 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
3204 g_assert_not_reached ();
3207 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3210 case OP_ATOMIC_EXCHANGE_I4
: {
3211 LLVMValueRef args
[2];
3213 g_assert (ins
->inst_offset
== 0);
3215 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3218 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
3221 case OP_ATOMIC_EXCHANGE_I8
: {
3222 LLVMValueRef args
[2];
3224 g_assert (ins
->inst_offset
== 0);
3226 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3227 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3228 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
3231 case OP_ATOMIC_ADD_NEW_I4
: {
3232 LLVMValueRef args
[2];
3234 g_assert (ins
->inst_offset
== 0);
3236 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3238 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
3241 case OP_ATOMIC_ADD_NEW_I8
: {
3242 LLVMValueRef args
[2];
3244 g_assert (ins
->inst_offset
== 0);
3246 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3247 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3248 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
3251 case OP_ATOMIC_CAS_I4
:
3252 case OP_ATOMIC_CAS_I8
: {
3253 LLVMValueRef args
[3];
3256 if (ins
->opcode
== OP_ATOMIC_CAS_I4
) {
3257 t
= LLVMInt32Type ();
3259 t
= LLVMInt64Type ();
3262 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
3264 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
3266 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
3267 values
[ins
->dreg
] = mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
3270 case OP_MEMORY_BARRIER
: {
3271 mono_llvm_build_fence (builder
);
3274 case OP_RELAXED_NOP
: {
3275 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3276 emit_call (ctx
, bb
, &builder
, LLVMGetNamedFunction (ctx
->module
, "llvm.x86.sse2.pause"), NULL
, 0);
3283 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3285 // 257 == FS segment register
3286 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
3288 // 256 == GS segment register
3289 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
3293 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
3295 LLVM_FAILURE (ctx
, "opcode tls-get");
3305 case OP_IADD_OVF_UN
:
3307 case OP_ISUB_OVF_UN
:
3309 case OP_IMUL_OVF_UN
:
3310 #if SIZEOF_VOID_P == 8
3312 case OP_LADD_OVF_UN
:
3314 case OP_LSUB_OVF_UN
:
3316 case OP_LMUL_OVF_UN
:
3319 LLVMValueRef args
[2], val
, ovf
, func
;
3321 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
3322 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
3323 func
= LLVMGetNamedFunction (module
, ovf_op_to_intrins (ins
->opcode
));
3325 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
3326 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
3327 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
3328 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
3329 CHECK_FAILURE (ctx
);
3330 builder
= ctx
->builder
;
3336 * We currently model them using arrays. Promotion to local vregs is
3337 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3338 * so we always have an entry in cfg->varinfo for them.
3339 * FIXME: Is this needed ?
3342 MonoClass
*klass
= ins
->klass
;
3343 LLVMValueRef args
[5];
3347 LLVM_FAILURE (ctx
, "!klass");
3351 if (!addresses
[ins
->dreg
])
3352 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3353 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3354 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
3355 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3357 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3358 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3359 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
3363 case OP_STOREV_MEMBASE
:
3364 case OP_LOADV_MEMBASE
:
3366 MonoClass
*klass
= ins
->klass
;
3367 LLVMValueRef src
= NULL
, dst
, args
[5];
3368 gboolean done
= FALSE
;
3372 LLVM_FAILURE (ctx
, "!klass");
3376 if (mini_is_gsharedvt_klass (cfg
, klass
)) {
3378 LLVM_FAILURE (ctx
, "gsharedvt");
3382 switch (ins
->opcode
) {
3383 case OP_STOREV_MEMBASE
:
3384 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
) {
3385 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3386 LLVM_FAILURE (ctx
, "storev_membase + write barriers");
3389 if (!addresses
[ins
->sreg1
]) {
3391 g_assert (values
[ins
->sreg1
]);
3392 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));
3393 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
3396 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3397 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3400 case OP_LOADV_MEMBASE
:
3401 if (!addresses
[ins
->dreg
])
3402 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3403 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3404 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3407 if (!addresses
[ins
->sreg1
])
3408 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
3409 if (!addresses
[ins
->dreg
])
3410 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3411 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3412 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3415 g_assert_not_reached ();
3417 CHECK_FAILURE (ctx
);
3424 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3425 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3427 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3428 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3429 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memcpy_func_name
), args
, memcpy_param_count
, "");
3432 case OP_LLVM_OUTARG_VT
:
3433 if (!addresses
[ins
->sreg1
]) {
3434 addresses
[ins
->sreg1
] = build_alloca (ctx
, &ins
->klass
->byval_arg
);
3435 g_assert (values
[ins
->sreg1
]);
3436 LLVMBuildStore (builder
, values
[ins
->sreg1
], addresses
[ins
->sreg1
]);
3438 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
3444 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3446 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
3449 case OP_LOADX_MEMBASE
: {
3450 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
3453 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3454 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
3457 case OP_STOREX_MEMBASE
: {
3458 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
3461 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3462 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
3469 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
3473 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
3479 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
3483 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
3487 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
3491 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
3494 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
3497 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
3500 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
3504 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
3515 LLVMValueRef v
= NULL
;
3517 switch (ins
->opcode
) {
3522 t
= LLVMVectorType (LLVMInt32Type (), 4);
3523 rt
= LLVMVectorType (LLVMFloatType (), 4);
3529 t
= LLVMVectorType (LLVMInt64Type (), 2);
3530 rt
= LLVMVectorType (LLVMDoubleType (), 2);
3533 t
= LLVMInt32Type ();
3534 rt
= LLVMInt32Type ();
3535 g_assert_not_reached ();
3538 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3539 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
3540 switch (ins
->opcode
) {
3543 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
3547 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
3551 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
3555 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
3558 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
3582 case OP_PADDB_SAT_UN
:
3583 case OP_PADDW_SAT_UN
:
3584 case OP_PSUBB_SAT_UN
:
3585 case OP_PSUBW_SAT_UN
:
3593 case OP_PMULW_HIGH_UN
: {
3594 LLVMValueRef args
[2];
3599 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3606 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
3610 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntSGT
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
3618 case OP_EXTRACTX_U2
:
3620 case OP_EXTRACT_U1
: {
3622 gboolean zext
= FALSE
;
3624 t
= simd_op_to_llvm_type (ins
->opcode
);
3626 switch (ins
->opcode
) {
3634 case OP_EXTRACTX_U2
:
3639 t
= LLVMInt32Type ();
3640 g_assert_not_reached ();
3643 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3644 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
3646 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
3655 case OP_EXPAND_R8
: {
3656 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3657 LLVMValueRef mask
[16], v
;
3659 for (i
= 0; i
< 16; ++i
)
3660 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3662 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
3664 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3665 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
3670 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3673 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3676 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3679 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3682 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3685 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3696 case OP_EXTRACT_MASK
:
3703 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
3705 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
3709 case OP_ICONV_TO_R8_RAW
:
3710 /* Same as OP_ICONV_TO_R8 */
3711 values
[ins
->dreg
] = convert (ctx
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType ());
3716 LLVMValueRef args
[3];
3720 args
[2] = LLVMConstInt (LLVMInt8Type (), ins
->inst_c0
, FALSE
);
3722 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
3727 /* This is only used for implementing shifts by non-immediate */
3728 values
[ins
->dreg
] = lhs
;
3739 LLVMValueRef args
[3];
3742 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
3744 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3755 case OP_PSHLQ_REG
: {
3756 LLVMValueRef args
[3];
3759 args
[1] = values
[ins
->sreg2
];
3761 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3768 case OP_PSHUFLEW_LOW
:
3769 case OP_PSHUFLEW_HIGH
: {
3771 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
3772 int i
, mask_size
= 0;
3773 int imask
= ins
->inst_c0
;
3775 /* Convert the x86 shuffle mask to LLVM's */
3776 switch (ins
->opcode
) {
3779 mask
[0] = ((imask
>> 0) & 3);
3780 mask
[1] = ((imask
>> 2) & 3);
3781 mask
[2] = ((imask
>> 4) & 3) + 4;
3782 mask
[3] = ((imask
>> 6) & 3) + 4;
3783 v1
= values
[ins
->sreg1
];
3784 v2
= values
[ins
->sreg2
];
3788 mask
[0] = ((imask
>> 0) & 1);
3789 mask
[1] = ((imask
>> 1) & 1) + 2;
3790 v1
= values
[ins
->sreg1
];
3791 v2
= values
[ins
->sreg2
];
3793 case OP_PSHUFLEW_LOW
:
3795 mask
[0] = ((imask
>> 0) & 3);
3796 mask
[1] = ((imask
>> 2) & 3);
3797 mask
[2] = ((imask
>> 4) & 3);
3798 mask
[3] = ((imask
>> 6) & 3);
3803 v1
= values
[ins
->sreg1
];
3804 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3806 case OP_PSHUFLEW_HIGH
:
3812 mask
[4] = 4 + ((imask
>> 0) & 3);
3813 mask
[5] = 4 + ((imask
>> 2) & 3);
3814 mask
[6] = 4 + ((imask
>> 4) & 3);
3815 mask
[7] = 4 + ((imask
>> 6) & 3);
3816 v1
= values
[ins
->sreg1
];
3817 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3821 mask
[0] = ((imask
>> 0) & 3);
3822 mask
[1] = ((imask
>> 2) & 3);
3823 mask
[2] = ((imask
>> 4) & 3);
3824 mask
[3] = ((imask
>> 6) & 3);
3825 v1
= values
[ins
->sreg1
];
3826 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3829 g_assert_not_reached ();
3831 for (i
= 0; i
< mask_size
; ++i
)
3832 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3834 values
[ins
->dreg
] =
3835 LLVMBuildShuffleVector (builder
, v1
, v2
,
3836 LLVMConstVector (mask_values
, mask_size
), dname
);
3840 case OP_UNPACK_LOWB
:
3841 case OP_UNPACK_LOWW
:
3842 case OP_UNPACK_LOWD
:
3843 case OP_UNPACK_LOWQ
:
3844 case OP_UNPACK_LOWPS
:
3845 case OP_UNPACK_LOWPD
:
3846 case OP_UNPACK_HIGHB
:
3847 case OP_UNPACK_HIGHW
:
3848 case OP_UNPACK_HIGHD
:
3849 case OP_UNPACK_HIGHQ
:
3850 case OP_UNPACK_HIGHPS
:
3851 case OP_UNPACK_HIGHPD
: {
3853 LLVMValueRef mask_values
[16];
3854 int i
, mask_size
= 0;
3855 gboolean low
= FALSE
;
3857 switch (ins
->opcode
) {
3858 case OP_UNPACK_LOWB
:
3862 case OP_UNPACK_LOWW
:
3866 case OP_UNPACK_LOWD
:
3867 case OP_UNPACK_LOWPS
:
3871 case OP_UNPACK_LOWQ
:
3872 case OP_UNPACK_LOWPD
:
3876 case OP_UNPACK_HIGHB
:
3879 case OP_UNPACK_HIGHW
:
3882 case OP_UNPACK_HIGHD
:
3883 case OP_UNPACK_HIGHPS
:
3886 case OP_UNPACK_HIGHQ
:
3887 case OP_UNPACK_HIGHPD
:
3891 g_assert_not_reached ();
3895 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3897 mask
[(i
* 2) + 1] = mask_size
+ i
;
3900 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3901 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
3902 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
3906 for (i
= 0; i
< mask_size
; ++i
)
3907 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3909 values
[ins
->dreg
] =
3910 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
3911 LLVMConstVector (mask_values
, mask_size
), dname
);
3916 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3917 LLVMValueRef v
, val
;
3919 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3920 val
= LLVMConstNull (t
);
3921 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3922 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
3924 values
[ins
->dreg
] = val
;
3928 case OP_DUPPS_HIGH
: {
3929 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3930 LLVMValueRef v1
, v2
, val
;
3933 if (ins
->opcode
== OP_DUPPS_LOW
) {
3934 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3935 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3937 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3938 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3940 val
= LLVMConstNull (t
);
3941 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3942 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3943 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3944 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3946 values
[ins
->dreg
] = val
;
3956 * EXCEPTION HANDLING
3958 case OP_IMPLICIT_EXCEPTION
:
3959 /* This marks a place where an implicit exception can happen */
3960 if (bb
->region
!= -1)
3961 LLVM_FAILURE (ctx
, "implicit-exception");
3965 MonoMethodSignature
*throw_sig
;
3966 LLVMValueRef callee
, arg
;
3967 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
3968 const char *icall_name
;
3970 callee
= rethrow
? ctx
->lmodule
->rethrow
: ctx
->lmodule
->throw;
3971 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3974 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
3975 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
3976 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
3977 if (cfg
->compile_aot
) {
3978 callee
= get_plt_entry (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3980 callee
= LLVMAddFunction (module
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
));
3984 * LLVM doesn't push the exception argument, so we need a different
3987 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3989 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3993 mono_memory_barrier ();
3995 ctx
->lmodule
->rethrow
= callee
;
3997 ctx
->lmodule
->throw = callee
;
3999 arg
= convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
4000 emit_call (ctx
, bb
, &builder
, callee
, &arg
, 1);
4003 case OP_CALL_HANDLER
: {
4005 * We don't 'call' handlers, but instead simply branch to them.
4006 * The code generated by ENDFINALLY will branch back to us.
4008 LLVMBasicBlockRef noex_bb
;
4010 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
4012 bb_list
= info
->call_handler_return_bbs
;
4015 * Set the indicator variable for the finally clause.
4017 lhs
= info
->finally_ind
;
4019 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
4021 /* Branch to the finally clause */
4022 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
4024 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
4025 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
4027 builder
= ctx
->builder
= create_builder (ctx
);
4028 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
4030 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
4033 case OP_START_HANDLER
: {
4036 case OP_ENDFINALLY
: {
4037 LLVMBasicBlockRef resume_bb
;
4038 MonoBasicBlock
*handler_bb
;
4039 LLVMValueRef val
, switch_ins
, callee
;
4043 handler_bb
= g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
4044 g_assert (handler_bb
);
4045 info
= &bblocks
[handler_bb
->block_num
];
4046 lhs
= info
->finally_ind
;
4049 bb_list
= info
->call_handler_return_bbs
;
4051 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
4053 /* Load the finally variable */
4054 val
= LLVMBuildLoad (builder
, lhs
, "");
4056 /* Reset the variable */
4057 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
4059 /* Branch to either resume_bb, or to the bblocks in bb_list */
4060 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
4062 * The other targets are added at the end to handle OP_CALL_HANDLER
4063 * opcodes processed later.
4065 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
4067 builder
= ctx
->builder
= create_builder (ctx
);
4068 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
4070 if (ctx
->cfg
->compile_aot
) {
4071 callee
= get_plt_entry (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
4073 callee
= LLVMGetNamedFunction (module
, "llvm_resume_unwind_trampoline");
4075 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
4077 LLVMBuildUnreachable (builder
);
4078 has_terminator
= TRUE
;
4084 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
4085 LLVM_FAILURE (ctx
, reason
);
4090 /* Convert the value to the type required by phi nodes */
4091 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
4092 if (!values
[ins
->dreg
])
4094 values
[ins
->dreg
] = addresses
[ins
->dreg
];
4096 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
4099 /* Add stores for volatile variables */
4100 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
4101 emit_volatile_store (ctx
, ins
->dreg
);
4104 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4105 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
4107 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
)
4108 LLVMBuildRetVoid (builder
);
4110 if (bb
== cfg
->bb_entry
)
4111 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
4120 * mono_llvm_check_method_supported:
4122 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4123 * compiling a method twice.
4126 mono_llvm_check_method_supported (MonoCompile
*cfg
)
4128 MonoMethodHeader
*header
= cfg
->header
;
4129 MonoExceptionClause
*clause
;
4132 if (cfg
->method
->save_lmf
) {
4133 cfg
->exception_message
= g_strdup ("lmf");
4134 cfg
->disable_llvm
= TRUE
;
4138 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4139 clause
= &header
->clauses
[i
];
4141 if (i
> 0 && clause
->try_offset
<= header
->clauses
[i
- 1].handler_offset
+ header
->clauses
[i
- 1].handler_len
) {
4143 * FIXME: Some tests still fail with nested clauses.
4145 cfg
->exception_message
= g_strdup ("nested clauses");
4146 cfg
->disable_llvm
= TRUE
;
4152 if (cfg
->method
->dynamic
) {
4153 cfg
->exception_message
= g_strdup ("dynamic.");
4154 cfg
->disable_llvm
= TRUE
;
4159 * mono_llvm_emit_method:
4161 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4164 mono_llvm_emit_method (MonoCompile
*cfg
)
4167 MonoMethodSignature
*sig
;
4169 LLVMTypeRef method_type
;
4170 LLVMValueRef method
= NULL
;
4172 LLVMValueRef
*values
;
4173 int i
, max_block_num
, bb_index
;
4174 gboolean last
= FALSE
;
4175 GPtrArray
*phi_values
;
4176 LLVMCallInfo
*linfo
;
4178 LLVMModuleRef module
;
4180 GPtrArray
*bblock_list
;
4181 MonoMethodHeader
*header
;
4182 MonoExceptionClause
*clause
;
4186 /* The code below might acquire the loader lock, so use it for global locking */
4187 mono_loader_lock ();
4189 /* Used to communicate with the callbacks */
4190 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
4192 ctx
= g_new0 (EmitContext
, 1);
4194 ctx
->mempool
= cfg
->mempool
;
4197 * This maps vregs to the LLVM instruction defining them
4199 values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4201 * This maps vregs for volatile variables to the LLVM instruction defining their
4204 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4205 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
4206 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
4207 phi_values
= g_ptr_array_new ();
4209 * This signals whenever the vreg was defined by a phi node with no input vars
4210 * (i.e. all its input bblocks end with NOT_REACHABLE).
4212 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
4213 /* Whenever the bblock is unreachable */
4214 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
4216 bblock_list
= g_ptr_array_new ();
4218 ctx
->values
= values
;
4219 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
4221 if (cfg
->compile_aot
) {
4222 ctx
->lmodule
= &aot_module
;
4223 method_name
= mono_aot_get_method_name (cfg
);
4224 cfg
->llvm_method_name
= g_strdup (method_name
);
4227 ctx
->lmodule
= &jit_module
;
4228 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
4231 module
= ctx
->module
= ctx
->lmodule
->module
;
4235 static int count
= 0;
4238 if (getenv ("LLVM_COUNT")) {
4239 if (count
== atoi (getenv ("LLVM_COUNT"))) {
4240 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
4244 if (count
> atoi (getenv ("LLVM_COUNT")))
4245 LLVM_FAILURE (ctx
, "");
4250 sig
= mono_method_signature (cfg
->method
);
4253 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4255 CHECK_FAILURE (ctx
);
4258 linfo
->rgctx_arg
= TRUE
;
4259 method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
, &sinfo
);
4260 CHECK_FAILURE (ctx
);
4263 * This maps parameter indexes in the original signature to the indexes in
4264 * the LLVM signature.
4266 ctx
->pindexes
= sinfo
.pindexes
;
4268 method
= LLVMAddFunction (module
, method_name
, method_type
);
4269 ctx
->lmethod
= method
;
4271 #ifdef LLVM_MONO_BRANCH
4272 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
4274 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4276 LLVMAddFunctionAttr (method
, LLVMUWTable
);
4278 if (cfg
->compile_aot
) {
4279 LLVMSetLinkage (method
, LLVMInternalLinkage
);
4280 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
4282 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4285 if (cfg
->method
->save_lmf
)
4286 LLVM_FAILURE (ctx
, "lmf");
4288 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
)
4289 LLVM_FAILURE (ctx
, "pinvoke signature");
4291 header
= cfg
->header
;
4292 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4293 clause
= &header
->clauses
[i
];
4294 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
)
4295 LLVM_FAILURE (ctx
, "non-finally/catch clause.");
4298 if (linfo
->rgctx_arg
) {
4299 ctx
->rgctx_arg
= LLVMGetParam (method
, sinfo
.rgctx_arg_pindex
);
4301 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4302 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4303 * CC_X86_64_Mono in X86CallingConv.td.
4305 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
4306 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
4308 if (cfg
->vret_addr
) {
4309 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, sinfo
.vret_arg_pindex
);
4310 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
4313 values
[cfg
->args
[0]->dreg
] = LLVMGetParam (method
, sinfo
.this_arg_pindex
);
4314 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
4317 names
= g_new (char *, sig
->param_count
);
4318 mono_method_get_param_names (cfg
->method
, (const char **) names
);
4320 for (i
= 0; i
< sig
->param_count
; ++i
) {
4323 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, sinfo
.pindexes
[i
]);
4324 if (names
[i
] && names
[i
][0] != '\0')
4325 name
= g_strdup_printf ("arg_%s", names
[i
]);
4327 name
= g_strdup_printf ("arg_%d", i
);
4328 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
4330 if (linfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
)
4331 LLVMAddAttribute (LLVMGetParam (method
, sinfo
.pindexes
[i
]), LLVMByValAttribute
);
4336 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
4337 max_block_num
= MAX (max_block_num
, bb
->block_num
);
4338 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
4340 /* Add branches between non-consecutive bblocks */
4341 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4342 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
4343 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
4345 MonoInst
*inst
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
4346 inst
->opcode
= OP_BR
;
4347 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
4348 mono_bblock_add_inst (bb
, inst
);
4353 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4354 * was later optimized away, so clear these flags, and add them back for the still
4355 * present OP_LDADDR instructions.
4357 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
4360 ins
= get_vreg_to_inst (cfg
, i
);
4361 if (ins
&& ins
!= cfg
->rgctx_var
)
4362 ins
->flags
&= ~MONO_INST_INDIRECT
;
4366 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4368 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4370 LLVMBuilderRef builder
;
4372 char dname_buf
[128];
4374 builder
= create_builder (ctx
);
4376 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4377 switch (ins
->opcode
) {
4382 LLVMTypeRef phi_type
= llvm_type_to_stack_type (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
4384 CHECK_FAILURE (ctx
);
4386 if (ins
->opcode
== OP_VPHI
) {
4387 /* Treat valuetype PHI nodes as operating on the address itself */
4388 g_assert (ins
->klass
);
4389 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
4393 * Have to precreate these, as they can be referenced by
4394 * earlier instructions.
4396 sprintf (dname_buf
, "t%d", ins
->dreg
);
4398 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
4400 if (ins
->opcode
== OP_VPHI
)
4401 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
4403 g_ptr_array_add (phi_values
, values
[ins
->dreg
]);
4406 * Set the expected type of the incoming arguments since these have
4407 * to have the same type.
4409 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4410 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4413 ctx
->vreg_types
[sreg1
] = phi_type
;
4418 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
4427 * Create an ordering for bblocks, use the depth first order first, then
4428 * put the exception handling bblocks last.
4430 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
4431 bb
= cfg
->bblocks
[bb_index
];
4432 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
4433 g_ptr_array_add (bblock_list
, bb
);
4434 bblocks
[bb
->block_num
].added
= TRUE
;
4438 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4439 if (!bblocks
[bb
->block_num
].added
)
4440 g_ptr_array_add (bblock_list
, bb
);
4444 * Second pass: generate code.
4446 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
4447 bb
= g_ptr_array_index (bblock_list
, bb_index
);
4449 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4452 process_bb (ctx
, bb
);
4453 CHECK_FAILURE (ctx
);
4456 /* Add incoming phi values */
4457 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4458 GSList
*l
, *ins_list
;
4460 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
4462 for (l
= ins_list
; l
; l
= l
->next
) {
4463 PhiNode
*node
= l
->data
;
4464 MonoInst
*phi
= node
->phi
;
4465 int sreg1
= node
->sreg
;
4466 LLVMBasicBlockRef in_bb
;
4471 in_bb
= get_end_bb (ctx
, node
->in_bb
);
4473 if (ctx
->unreachable
[node
->in_bb
->block_num
])
4476 if (!values
[sreg1
])
4477 /* Can happen with values in EH clauses */
4478 LLVM_FAILURE (ctx
, "incoming phi sreg1");
4480 if (phi
->opcode
== OP_VPHI
) {
4481 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4482 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
4484 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4485 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
4490 /* Create the SWITCH statements for ENDFINALLY instructions */
4491 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4492 BBInfo
*info
= &bblocks
[bb
->block_num
];
4494 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
4495 LLVMValueRef switch_ins
= l
->data
;
4496 GSList
*bb_list
= info
->call_handler_return_bbs
;
4498 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
4499 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), g_slist_nth (bb_list
, i
)->data
);
4503 if (cfg
->verbose_level
> 1)
4504 mono_llvm_dump_value (method
);
4506 mark_as_used (module
, method
);
4508 if (cfg
->compile_aot
) {
4509 /* Don't generate native code, keep the LLVM IR */
4510 if (cfg
->compile_aot
&& cfg
->verbose_level
)
4511 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), method_name
);
4513 //LLVMVerifyFunction(method, 0);
4515 mono_llvm_optimize_method (method
);
4517 if (cfg
->verbose_level
> 1)
4518 mono_llvm_dump_value (method
);
4520 cfg
->native_code
= LLVMGetPointerToGlobal (ee
, method
);
4522 /* Set by emit_cb */
4523 g_assert (cfg
->code_len
);
4525 /* FIXME: Free the LLVM IL for the function */
4533 /* Need to add unused phi nodes as they can be referenced by other values */
4534 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (method
, "PHI_BB");
4535 LLVMBuilderRef builder
;
4537 builder
= create_builder (ctx
);
4538 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
4540 for (i
= 0; i
< phi_values
->len
; ++i
) {
4541 LLVMValueRef v
= g_ptr_array_index (phi_values
, i
);
4542 if (LLVMGetInstructionParent (v
) == NULL
)
4543 LLVMInsertIntoBuilder (builder
, v
);
4546 LLVMDeleteFunction (method
);
4551 g_free (ctx
->addresses
);
4552 g_free (ctx
->vreg_types
);
4553 g_free (ctx
->vreg_cli_types
);
4554 g_free (ctx
->pindexes
);
4555 g_free (ctx
->is_dead
);
4556 g_free (ctx
->unreachable
);
4557 g_ptr_array_free (phi_values
, TRUE
);
4558 g_free (ctx
->bblocks
);
4559 g_hash_table_destroy (ctx
->region_to_handler
);
4560 g_free (method_name
);
4561 g_ptr_array_free (bblock_list
, TRUE
);
4563 for (l
= ctx
->builders
; l
; l
= l
->next
) {
4564 LLVMBuilderRef builder
= l
->data
;
4565 LLVMDisposeBuilder (builder
);
4570 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
4572 mono_loader_unlock ();
4576 * mono_llvm_emit_call:
4578 * Same as mono_arch_emit_call () for LLVM.
4581 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
4584 MonoMethodSignature
*sig
;
4585 int i
, n
, stack_size
;
4590 sig
= call
->signature
;
4591 n
= sig
->param_count
+ sig
->hasthis
;
4593 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4595 if (cfg
->disable_llvm
)
4598 if (sig
->call_convention
== MONO_CALL_VARARG
) {
4599 cfg
->exception_message
= g_strdup ("varargs");
4600 cfg
->disable_llvm
= TRUE
;
4603 for (i
= 0; i
< n
; ++i
) {
4606 ainfo
= call
->cinfo
->args
+ i
;
4608 in
= call
->args
[i
];
4610 /* Simply remember the arguments */
4611 switch (ainfo
->storage
) {
4613 case LLVMArgInFPReg
: {
4614 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? &mono_get_intptr_class ()->byval_arg
: sig
->params
[i
- sig
->hasthis
];
4616 if (!t
->byref
&& (t
->type
== MONO_TYPE_R8
|| t
->type
== MONO_TYPE_R4
)) {
4617 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
4618 ins
->dreg
= mono_alloc_freg (cfg
);
4620 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
4621 ins
->dreg
= mono_alloc_ireg (cfg
);
4623 ins
->sreg1
= in
->dreg
;
4626 case LLVMArgVtypeByVal
:
4627 case LLVMArgVtypeInReg
:
4628 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
4629 ins
->dreg
= mono_alloc_ireg (cfg
);
4630 ins
->sreg1
= in
->dreg
;
4631 ins
->klass
= mono_class_from_mono_type (sig
->params
[i
- sig
->hasthis
]);
4634 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4635 cfg
->exception_message
= g_strdup ("ainfo->storage");
4636 cfg
->disable_llvm
= TRUE
;
4640 if (!cfg
->disable_llvm
) {
4641 MONO_ADD_INS (cfg
->cbb
, ins
);
4642 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
4647 static unsigned char*
4648 alloc_cb (LLVMValueRef function
, int size
)
4652 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4656 return mono_domain_code_reserve (cfg
->domain
, size
);
4658 return mono_domain_code_reserve (mono_domain_get (), size
);
4663 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
4667 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4669 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
4673 exception_cb (void *data
)
4676 MonoJitExceptionInfo
*ei
;
4677 guint32 ei_len
, i
, j
, nested_len
, nindex
;
4678 gpointer
*type_info
;
4679 int this_reg
, this_offset
;
4681 cfg
= mono_native_tls_get_value (current_cfg_tls_id
);
4685 * data points to a DWARF FDE structure, convert it to our unwind format and
4687 * An alternative would be to save it directly, and modify our unwinder to work
4690 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
);
4692 /* Count nested clauses */
4694 for (i
= 0; i
< ei_len
; ++i
) {
4695 for (j
= 0; j
< ei_len
; ++j
) {
4696 gint32 cindex1
= *(gint32
*)type_info
[i
];
4697 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4698 gint32 cindex2
= *(gint32
*)type_info
[j
];
4699 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4701 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4707 cfg
->llvm_ex_info
= mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
4708 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
4709 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
4710 /* Fill the rest of the information from the type info */
4711 for (i
= 0; i
< ei_len
; ++i
) {
4712 gint32 clause_index
= *(gint32
*)type_info
[i
];
4713 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
4715 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
4716 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
4720 * For nested clauses, the LLVM produced exception info associates the try interval with
4721 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4723 /* FIXME: These should be order with the normal clauses */
4725 for (i
= 0; i
< ei_len
; ++i
) {
4726 for (j
= 0; j
< ei_len
; ++j
) {
4727 gint32 cindex1
= *(gint32
*)type_info
[i
];
4728 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4729 gint32 cindex2
= *(gint32
*)type_info
[j
];
4730 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4732 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4734 * The try interval comes from the nested clause, everything else from the
4737 memcpy (&cfg
->llvm_ex_info
[nindex
], &cfg
->llvm_ex_info
[j
], sizeof (MonoJitExceptionInfo
));
4738 cfg
->llvm_ex_info
[nindex
].try_start
= cfg
->llvm_ex_info
[i
].try_start
;
4739 cfg
->llvm_ex_info
[nindex
].try_end
= cfg
->llvm_ex_info
[i
].try_end
;
4744 g_assert (nindex
== ei_len
+ nested_len
);
4745 cfg
->llvm_this_reg
= this_reg
;
4746 cfg
->llvm_this_offset
= this_offset
;
4748 /* type_info [i] is cfg mempool allocated, no need to free it */
4755 dlsym_cb (const char *name
, void **symbol
)
4761 if (!strcmp (name
, "__bzero")) {
4762 *symbol
= (void*)bzero
;
4764 current
= mono_dl_open (NULL
, 0, NULL
);
4767 err
= mono_dl_symbol (current
, name
, symbol
);
4769 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4770 *symbol
= (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8
*)(*symbol
));
4776 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
4778 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
4782 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
4784 LLVMTypeRef param_types
[4];
4786 param_types
[0] = param_type1
;
4787 param_types
[1] = param_type2
;
4789 AddFunc (module
, name
, ret_type
, param_types
, 2);
4793 add_intrinsics (LLVMModuleRef module
)
4795 /* Emit declarations of instrinsics */
4797 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4798 * type doesn't seem to do any locking.
4801 LLVMTypeRef memset_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4803 memset_param_count
= 5;
4804 memset_func_name
= "llvm.memset.p0i8.i32";
4806 LLVMAddFunction (module
, memset_func_name
, LLVMFunctionType (LLVMVoidType (), memset_params
, memset_param_count
, FALSE
));
4810 LLVMTypeRef memcpy_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4812 memcpy_param_count
= 5;
4813 memcpy_func_name
= "llvm.memcpy.p0i8.p0i8.i32";
4815 LLVMAddFunction (module
, memcpy_func_name
, LLVMFunctionType (LLVMVoidType (), memcpy_params
, memcpy_param_count
, FALSE
));
4819 LLVMTypeRef params
[] = { LLVMDoubleType () };
4821 LLVMAddFunction (module
, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4822 LLVMAddFunction (module
, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4823 LLVMAddFunction (module
, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4825 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4826 LLVMAddFunction (module
, "fabs", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4830 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
4831 LLVMTypeRef ovf_params_i32
[] = { LLVMInt32Type (), LLVMInt32Type () };
4833 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4834 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4835 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4836 LLVMAddFunction (module
, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4837 LLVMAddFunction (module
, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4838 LLVMAddFunction (module
, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4842 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
4843 LLVMTypeRef ovf_params_i64
[] = { LLVMInt64Type (), LLVMInt64Type () };
4845 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4846 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4847 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4848 LLVMAddFunction (module
, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4849 LLVMAddFunction (module
, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4850 LLVMAddFunction (module
, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4854 LLVMTypeRef struct_ptr
= LLVMPointerType (LLVMStructType (NULL
, 0, FALSE
), 0);
4855 LLVMTypeRef invariant_start_params
[] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4856 LLVMTypeRef invariant_end_params
[] = { struct_ptr
, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4858 LLVMAddFunction (module
, "llvm.invariant.start", LLVMFunctionType (struct_ptr
, invariant_start_params
, 2, FALSE
));
4860 LLVMAddFunction (module
, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params
, 3, FALSE
));
4865 LLVMTypeRef arg_types
[2];
4866 LLVMTypeRef ret_type
;
4868 arg_types
[0] = LLVMPointerType (LLVMInt8Type (), 0);
4869 arg_types
[1] = LLVMPointerType (LLVMInt8Type (), 0);
4870 ret_type
= LLVMInt32Type ();
4872 LLVMAddFunction (module
, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4874 LLVMAddFunction (module
, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4877 /* SSE intrinsics */
4879 LLVMTypeRef ret_type
, arg_types
[16];
4882 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4883 arg_types
[0] = ret_type
;
4884 arg_types
[1] = ret_type
;
4885 AddFunc (module
, "llvm.x86.sse41.pminud", ret_type
, arg_types
, 2);
4886 AddFunc (module
, "llvm.x86.sse41.pmaxud", ret_type
, arg_types
, 2);
4888 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4889 arg_types
[0] = ret_type
;
4890 arg_types
[1] = ret_type
;
4891 AddFunc (module
, "llvm.x86.sse41.pminuw", ret_type
, arg_types
, 2);
4892 AddFunc (module
, "llvm.x86.sse2.pmins.w", ret_type
, arg_types
, 2);
4893 AddFunc (module
, "llvm.x86.sse41.pmaxuw", ret_type
, arg_types
, 2);
4894 AddFunc (module
, "llvm.x86.sse2.padds.w", ret_type
, arg_types
, 2);
4895 AddFunc (module
, "llvm.x86.sse2.psubs.w", ret_type
, arg_types
, 2);
4896 AddFunc (module
, "llvm.x86.sse2.paddus.w", ret_type
, arg_types
, 2);
4897 AddFunc (module
, "llvm.x86.sse2.psubus.w", ret_type
, arg_types
, 2);
4898 AddFunc (module
, "llvm.x86.sse2.pavg.w", ret_type
, arg_types
, 2);
4899 AddFunc (module
, "llvm.x86.sse2.pmulh.w", ret_type
, arg_types
, 2);
4900 AddFunc (module
, "llvm.x86.sse2.pmulhu.w", ret_type
, arg_types
, 2);
4902 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4903 arg_types
[0] = ret_type
;
4904 arg_types
[1] = ret_type
;
4905 AddFunc (module
, "llvm.x86.sse2.pminu.b", ret_type
, arg_types
, 2);
4906 AddFunc (module
, "llvm.x86.sse2.pmaxu.b", ret_type
, arg_types
, 2);
4907 AddFunc (module
, "llvm.x86.sse2.padds.b", ret_type
, arg_types
, 2);
4908 AddFunc (module
, "llvm.x86.sse2.psubs.b", ret_type
, arg_types
, 2);
4909 AddFunc (module
, "llvm.x86.sse2.paddus.b", ret_type
, arg_types
, 2);
4910 AddFunc (module
, "llvm.x86.sse2.psubus.b", ret_type
, arg_types
, 2);
4911 AddFunc (module
, "llvm.x86.sse2.pavg.b", ret_type
, arg_types
, 2);
4913 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4914 arg_types
[0] = ret_type
;
4915 arg_types
[1] = ret_type
;
4916 AddFunc (module
, "llvm.x86.sse2.min.pd", ret_type
, arg_types
, 2);
4917 AddFunc (module
, "llvm.x86.sse2.max.pd", ret_type
, arg_types
, 2);
4918 AddFunc (module
, "llvm.x86.sse3.hadd.pd", ret_type
, arg_types
, 2);
4919 AddFunc (module
, "llvm.x86.sse3.hsub.pd", ret_type
, arg_types
, 2);
4920 AddFunc (module
, "llvm.x86.sse3.addsub.pd", ret_type
, arg_types
, 2);
4922 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4923 arg_types
[0] = ret_type
;
4924 arg_types
[1] = ret_type
;
4925 AddFunc (module
, "llvm.x86.sse.min.ps", ret_type
, arg_types
, 2);
4926 AddFunc (module
, "llvm.x86.sse.max.ps", ret_type
, arg_types
, 2);
4927 AddFunc (module
, "llvm.x86.sse3.hadd.ps", ret_type
, arg_types
, 2);
4928 AddFunc (module
, "llvm.x86.sse3.hsub.ps", ret_type
, arg_types
, 2);
4929 AddFunc (module
, "llvm.x86.sse3.addsub.ps", ret_type
, arg_types
, 2);
4932 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4933 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
4934 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
4935 AddFunc (module
, "llvm.x86.sse2.packsswb.128", ret_type
, arg_types
, 2);
4936 AddFunc (module
, "llvm.x86.sse2.packuswb.128", ret_type
, arg_types
, 2);
4937 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4938 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
4939 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
4940 AddFunc (module
, "llvm.x86.sse2.packssdw.128", ret_type
, arg_types
, 2);
4941 AddFunc (module
, "llvm.x86.sse41.packusdw", ret_type
, arg_types
, 2);
4944 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4945 arg_types
[0] = ret_type
;
4946 arg_types
[1] = ret_type
;
4947 arg_types
[2] = LLVMInt8Type ();
4948 AddFunc (module
, "llvm.x86.sse2.cmp.pd", ret_type
, arg_types
, 3);
4949 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4950 arg_types
[0] = ret_type
;
4951 arg_types
[1] = ret_type
;
4952 arg_types
[2] = LLVMInt8Type ();
4953 AddFunc (module
, "llvm.x86.sse.cmp.ps", ret_type
, arg_types
, 3);
4955 /* Conversion ops */
4956 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4957 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
4958 AddFunc (module
, "llvm.x86.sse2.cvtdq2pd", ret_type
, arg_types
, 1);
4959 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4960 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
4961 AddFunc (module
, "llvm.x86.sse2.cvtdq2ps", ret_type
, arg_types
, 1);
4962 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4963 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
4964 AddFunc (module
, "llvm.x86.sse2.cvtpd2dq", ret_type
, arg_types
, 1);
4965 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4966 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
4967 AddFunc (module
, "llvm.x86.sse2.cvtps2dq", ret_type
, arg_types
, 1);
4968 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4969 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
4970 AddFunc (module
, "llvm.x86.sse2.cvtpd2ps", ret_type
, arg_types
, 1);
4971 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4972 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
4973 AddFunc (module
, "llvm.x86.sse2.cvtps2pd", ret_type
, arg_types
, 1);
4975 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4976 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
4977 AddFunc (module
, "llvm.x86.sse2.cvttpd2dq", ret_type
, arg_types
, 1);
4978 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4979 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
4980 AddFunc (module
, "llvm.x86.sse2.cvttps2dq", ret_type
, arg_types
, 1);
4983 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4984 arg_types
[0] = ret_type
;
4985 AddFunc (module
, "llvm.x86.sse2.sqrt.pd", ret_type
, arg_types
, 1);
4986 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4987 arg_types
[0] = ret_type
;
4988 AddFunc (module
, "llvm.x86.sse.sqrt.ps", ret_type
, arg_types
, 1);
4989 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4990 arg_types
[0] = ret_type
;
4991 AddFunc (module
, "llvm.x86.sse.rsqrt.ps", ret_type
, arg_types
, 1);
4992 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4993 arg_types
[0] = ret_type
;
4994 AddFunc (module
, "llvm.x86.sse.rcp.ps", ret_type
, arg_types
, 1);
4997 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4998 arg_types
[0] = ret_type
;
4999 arg_types
[1] = LLVMInt32Type ();
5000 AddFunc (module
, "llvm.x86.sse2.psrli.w", ret_type
, arg_types
, 2);
5001 AddFunc (module
, "llvm.x86.sse2.psrai.w", ret_type
, arg_types
, 2);
5002 AddFunc (module
, "llvm.x86.sse2.pslli.w", ret_type
, arg_types
, 2);
5003 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5004 arg_types
[0] = ret_type
;
5005 arg_types
[1] = LLVMInt32Type ();
5006 AddFunc (module
, "llvm.x86.sse2.psrli.d", ret_type
, arg_types
, 2);
5007 AddFunc (module
, "llvm.x86.sse2.psrai.d", ret_type
, arg_types
, 2);
5008 AddFunc (module
, "llvm.x86.sse2.pslli.d", ret_type
, arg_types
, 2);
5009 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
5010 arg_types
[0] = ret_type
;
5011 arg_types
[1] = LLVMInt32Type ();
5012 AddFunc (module
, "llvm.x86.sse2.psrli.q", ret_type
, arg_types
, 2);
5013 AddFunc (module
, "llvm.x86.sse2.pslli.q", ret_type
, arg_types
, 2);
5016 ret_type
= LLVMInt32Type ();
5017 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
5018 AddFunc (module
, "llvm.x86.sse2.pmovmskb.128", ret_type
, arg_types
, 1);
5021 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
5023 /* Load/Store intrinsics */
5025 LLVMTypeRef arg_types
[5];
5029 for (i
= 1; i
<= 8; i
*= 2) {
5030 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5031 arg_types
[1] = LLVMInt32Type ();
5032 arg_types
[2] = LLVMInt1Type ();
5033 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
5034 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMIntType (i
* 8), arg_types
, 3, FALSE
));
5036 arg_types
[0] = LLVMIntType (i
* 8);
5037 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5038 arg_types
[2] = LLVMInt32Type ();
5039 arg_types
[3] = LLVMInt1Type ();
5040 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
5041 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMVoidType (), arg_types
, 4, FALSE
));
5047 mono_llvm_init (void)
5049 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
5053 init_jit_module (void)
5055 MonoJitICallInfo
*info
;
5057 if (jit_module_inited
)
5060 mono_loader_lock ();
5062 if (jit_module_inited
) {
5063 mono_loader_unlock ();
5067 jit_module
.module
= LLVMModuleCreateWithName ("mono");
5069 ee
= mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module
.module
), alloc_cb
, emitted_cb
, exception_cb
, dlsym_cb
);
5071 add_intrinsics (jit_module
.module
);
5073 jit_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5075 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5077 LLVMAddGlobalMapping (ee
, LLVMGetNamedFunction (jit_module
.module
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
5079 jit_module_inited
= TRUE
;
5081 mono_loader_unlock ();
5085 mono_llvm_cleanup (void)
5088 mono_llvm_dispose_ee (ee
);
5090 if (jit_module
.llvm_types
)
5091 g_hash_table_destroy (jit_module
.llvm_types
);
5093 if (aot_module
.module
)
5094 LLVMDisposeModule (aot_module
.module
);
5096 LLVMContextDispose (LLVMGetGlobalContext ());
5100 mono_llvm_create_aot_module (const char *got_symbol
)
5102 /* Delete previous module */
5103 if (aot_module
.plt_entries
)
5104 g_hash_table_destroy (aot_module
.plt_entries
);
5105 if (aot_module
.module
)
5106 LLVMDisposeModule (aot_module
.module
);
5108 memset (&aot_module
, 0, sizeof (aot_module
));
5110 aot_module
.module
= LLVMModuleCreateWithName ("aot");
5111 aot_module
.got_symbol
= got_symbol
;
5113 add_intrinsics (aot_module
.module
);
5117 * We couldn't compute the type of the LLVM global representing the got because
5118 * its size is only known after all the methods have been emitted. So create
5119 * a dummy variable, and replace all uses it with the real got variable when
5120 * its size is known in mono_llvm_emit_aot_module ().
5123 LLVMTypeRef got_type
= LLVMArrayType (IntPtrType (), 0);
5125 aot_module
.got_var
= LLVMAddGlobal (aot_module
.module
, got_type
, "mono_dummy_got");
5126 LLVMSetInitializer (aot_module
.got_var
, LLVMConstNull (got_type
));
5129 /* Add a dummy personality function */
5131 LLVMBasicBlockRef lbb
;
5132 LLVMBuilderRef lbuilder
;
5133 LLVMValueRef personality
;
5135 personality
= LLVMAddFunction (aot_module
.module
, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
5136 LLVMSetLinkage (personality
, LLVMPrivateLinkage
);
5137 lbb
= LLVMAppendBasicBlock (personality
, "BB0");
5138 lbuilder
= LLVMCreateBuilder ();
5139 LLVMPositionBuilderAtEnd (lbuilder
, lbb
);
5140 LLVMBuildRetVoid (lbuilder
);
5143 aot_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5144 aot_module
.plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
5148 * Emit the aot module into the LLVM bitcode file FILENAME.
5151 mono_llvm_emit_aot_module (const char *filename
, int got_size
)
5153 LLVMTypeRef got_type
;
5154 LLVMValueRef real_got
;
5157 * Create the real got variable and replace all uses of the dummy variable with
5160 got_type
= LLVMArrayType (IntPtrType (), got_size
);
5161 real_got
= LLVMAddGlobal (aot_module
.module
, got_type
, aot_module
.got_symbol
);
5162 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
5163 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
5165 mono_llvm_replace_uses_of (aot_module
.got_var
, real_got
);
5167 mark_as_used (aot_module
.module
, real_got
);
5169 /* Delete the dummy got so it doesn't become a global */
5170 LLVMDeleteGlobal (aot_module
.got_var
);
5176 if (LLVMVerifyModule (aot_module
.module
, LLVMReturnStatusAction
, &verifier_err
)) {
5177 g_assert_not_reached ();
5182 LLVMWriteBitcodeToFile (aot_module
.module
, filename
);
5187 - Emit LLVM IR from the mono IR using the LLVM C API.
5188 - The original arch specific code remains, so we can fall back to it if we run
5189 into something we can't handle.
5193 A partial list of issues:
5194 - Handling of opcodes which can throw exceptions.
5196 In the mono JIT, these are implemented using code like this:
5203 push throw_pos - method
5204 call <exception trampoline>
5206 The problematic part is push throw_pos - method, which cannot be represented
5207 in the LLVM IR, since it does not support label values.
5208 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5209 be implemented in JIT mode ?
5210 -> a possible but slower implementation would use the normal exception
5211 throwing code but it would need to control the placement of the throw code
5212 (it needs to be exactly after the compare+branch).
5213 -> perhaps add a PC offset intrinsics ?
5215 - efficient implementation of .ovf opcodes.
5217 These are currently implemented as:
5218 <ins which sets the condition codes>
5221 Some overflow opcodes are now supported by LLVM SVN.
5223 - exception handling, unwinding.
5224 - SSA is disabled for methods with exception handlers
5225 - How to obtain unwind info for LLVM compiled methods ?
5226 -> this is now solved by converting the unwind info generated by LLVM
5228 - LLVM uses the c++ exception handling framework, while we use our home grown
5229 code, and couldn't use the c++ one:
5230 - its not supported under VC++, other exotic platforms.
5231 - it might be impossible to support filter clauses with it.
5235 The trampolines need a predictable call sequence, since they need to disasm
5236 the calling code to obtain register numbers / offsets.
5238 LLVM currently generates this code in non-JIT mode:
5239 mov -0x98(%rax),%eax
5241 Here, the vtable pointer is lost.
5242 -> solution: use one vtable trampoline per class.
5244 - passing/receiving the IMT pointer/RGCTX.
5245 -> solution: pass them as normal arguments ?
5249 LLVM does not allow the specification of argument registers etc. This means
5250 that all calls are made according to the platform ABI.
5252 - passing/receiving vtypes.
5254 Vtypes passed/received in registers are handled by the front end by using
5255 a signature with scalar arguments, and loading the parts of the vtype into those
5258 Vtypes passed on the stack are handled using the 'byval' attribute.
5262 Supported though alloca, we need to emit the load/store code.
5266 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5267 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5268 This is made easier because the IR is already in SSA form.
5269 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5270 types are frequently used incorrectly.
5275 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5276 append the AOT data structures to that file. For methods which cannot be
5277 handled by LLVM, the normal JIT compiled versions are used.
5280 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5281 * - each bblock should end with a branch
5282 * - setting the return value, making cfg->ret non-volatile
5283 * - avoid some transformations in the JIT which make it harder for us to generate
5285 * - use pointer types to help optimizations.