2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
11 #ifndef __STDC_LIMIT_MACROS
12 #define __STDC_LIMIT_MACROS
14 #ifndef __STDC_CONSTANT_MACROS
15 #define __STDC_CONSTANT_MACROS
18 #include "llvm-c/Core.h"
19 #include "llvm-c/ExecutionEngine.h"
20 #include "llvm-c/BitWriter.h"
21 #include "llvm-c/Analysis.h"
23 #include "mini-llvm-cpp.h"
26 * Information associated by mono with LLVM modules.
30 LLVMValueRef
throw, rethrow
, throw_corlib_exception
;
31 GHashTable
*llvm_types
;
33 const char *got_symbol
;
34 GHashTable
*plt_entries
;
38 * Information associated by the backend with mono basic blocks.
41 LLVMBasicBlockRef bblock
, end_bblock
;
42 LLVMValueRef finally_ind
;
43 gboolean added
, invoke_target
;
45 * If this bblock is the start of a finally clause, this is a list of bblocks it
46 * needs to branch to in ENDFINALLY.
48 GSList
*call_handler_return_bbs
;
50 * If this bblock is the start of a finally clause, this is the bblock that
51 * CALL_HANDLER needs to branch to.
53 LLVMBasicBlockRef call_handler_target_bb
;
54 /* The list of switch statements generated by ENDFINALLY instructions */
55 GSList
*endfinally_switch_ins_list
;
60 * Structure containing emit state
65 /* Maps method names to the corresponding LLVMValueRef */
66 GHashTable
*emitted_method_decls
;
70 MonoLLVMModule
*lmodule
;
73 int sindex
, default_index
, ex_index
;
74 LLVMBuilderRef builder
;
75 LLVMValueRef
*values
, *addresses
;
76 MonoType
**vreg_cli_types
;
78 MonoMethodSignature
*sig
;
80 GHashTable
*region_to_handler
;
81 LLVMBuilderRef alloca_builder
;
82 LLVMValueRef last_alloca
;
83 LLVMValueRef rgctx_arg
;
84 LLVMTypeRef
*vreg_types
;
86 gboolean
*unreachable
;
95 MonoBasicBlock
*in_bb
;
100 * Instruction metadata
101 * This is the same as ins_info, but LREG != IREG.
109 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
110 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
117 /* keep in sync with the enum in mini.h */
120 #include "mini-ops.h"
125 #if SIZEOF_VOID_P == 4
126 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
128 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
131 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
134 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
136 #define TRACE_FAILURE(msg)
140 #define IS_TARGET_X86 1
142 #define IS_TARGET_X86 0
145 #define LLVM_FAILURE(ctx, reason) do { \
146 TRACE_FAILURE (reason); \
147 (ctx)->cfg->exception_message = g_strdup (reason); \
148 (ctx)->cfg->disable_llvm = TRUE; \
152 #define CHECK_FAILURE(ctx) do { \
153 if ((ctx)->cfg->disable_llvm) \
157 static LLVMIntPredicate cond_to_llvm_cond
[] = {
170 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
183 static LLVMExecutionEngineRef ee
;
184 static guint32 current_cfg_tls_id
;
186 static MonoLLVMModule jit_module
, aot_module
;
187 static gboolean jit_module_inited
;
188 static int memset_param_count
, memcpy_param_count
;
189 static const char *memset_func_name
;
190 static const char *memcpy_func_name
;
191 static const char *eh_selector_name
;
193 static void init_jit_module (void);
198 * The LLVM type with width == sizeof (gpointer)
203 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
209 * Return the size of the LLVM representation of the vtype T.
212 get_vtype_size (MonoType
*t
)
216 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
218 while (size
< sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
225 * simd_class_to_llvm_type:
227 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
230 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
232 if (!strcmp (klass
->name
, "Vector2d")) {
233 return LLVMVectorType (LLVMDoubleType (), 2);
234 } else if (!strcmp (klass
->name
, "Vector2l")) {
235 return LLVMVectorType (LLVMInt64Type (), 2);
236 } else if (!strcmp (klass
->name
, "Vector2ul")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass
->name
, "Vector4i")) {
239 return LLVMVectorType (LLVMInt32Type (), 4);
240 } else if (!strcmp (klass
->name
, "Vector4ui")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass
->name
, "Vector4f")) {
243 return LLVMVectorType (LLVMFloatType (), 4);
244 } else if (!strcmp (klass
->name
, "Vector8s")) {
245 return LLVMVectorType (LLVMInt16Type (), 8);
246 } else if (!strcmp (klass
->name
, "Vector8us")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass
->name
, "Vector16sb")) {
249 return LLVMVectorType (LLVMInt8Type (), 16);
250 } else if (!strcmp (klass
->name
, "Vector16b")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
253 printf ("%s\n", klass
->name
);
259 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
260 static inline G_GNUC_UNUSED LLVMTypeRef
261 type_to_simd_type (int type
)
265 return LLVMVectorType (LLVMInt8Type (), 16);
267 return LLVMVectorType (LLVMInt16Type (), 8);
269 return LLVMVectorType (LLVMInt32Type (), 4);
271 return LLVMVectorType (LLVMInt64Type (), 2);
273 return LLVMVectorType (LLVMDoubleType (), 2);
275 return LLVMVectorType (LLVMFloatType (), 4);
277 g_assert_not_reached ();
285 * Return the LLVM type corresponding to T.
288 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
291 return LLVMPointerType (LLVMInt8Type (), 0);
294 return LLVMVoidType ();
296 return LLVMInt8Type ();
298 return LLVMInt16Type ();
300 return LLVMInt32Type ();
302 return LLVMInt8Type ();
304 return LLVMInt16Type ();
306 return LLVMInt32Type ();
307 case MONO_TYPE_BOOLEAN
:
308 return LLVMInt8Type ();
311 return LLVMInt64Type ();
313 return LLVMInt16Type ();
315 return LLVMFloatType ();
317 return LLVMDoubleType ();
320 return IntPtrType ();
321 case MONO_TYPE_OBJECT
:
322 case MONO_TYPE_CLASS
:
323 case MONO_TYPE_ARRAY
:
324 case MONO_TYPE_SZARRAY
:
325 case MONO_TYPE_STRING
:
327 return LLVMPointerType (IntPtrType (), 0);
330 /* Because of generic sharing */
331 return IntPtrType ();
332 case MONO_TYPE_GENERICINST
:
333 if (!mono_type_generic_inst_is_valuetype (t
))
334 return IntPtrType ();
336 case MONO_TYPE_VALUETYPE
:
337 case MONO_TYPE_TYPEDBYREF
: {
341 klass
= mono_class_from_mono_type (t
);
343 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
344 return simd_class_to_llvm_type (ctx
, klass
);
347 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
348 ltype
= g_hash_table_lookup (ctx
->lmodule
->llvm_types
, klass
);
351 LLVMTypeRef
*eltypes
;
353 size
= get_vtype_size (t
);
355 eltypes
= g_new (LLVMTypeRef
, size
);
356 for (i
= 0; i
< size
; ++i
)
357 eltypes
[i
] = LLVMInt8Type ();
359 /* We couldn't name these types since LLVM uses structural type equality */
360 ltype
= LLVMStructType (eltypes
, size
, FALSE
);
361 g_hash_table_insert (ctx
->lmodule
->llvm_types
, klass
, ltype
);
368 printf ("X: %d\n", t
->type
);
369 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
370 ctx
->cfg
->disable_llvm
= TRUE
;
378 * Return whenever T is an unsigned int type.
381 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
397 * type_to_llvm_arg_type:
399 * Same as type_to_llvm_type, but treat i8/i16 as i32.
402 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
404 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
406 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
408 * LLVM generates code which only sets the lower bits, while JITted
409 * code expects all the bits to be set.
411 ptype
= LLVMInt32Type ();
418 * llvm_type_to_stack_type:
420 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
423 static G_GNUC_UNUSED LLVMTypeRef
424 llvm_type_to_stack_type (LLVMTypeRef type
)
428 if (type
== LLVMInt8Type ())
429 return LLVMInt32Type ();
430 else if (type
== LLVMInt16Type ())
431 return LLVMInt32Type ();
432 else if (type
== LLVMFloatType ())
433 return LLVMDoubleType ();
439 * regtype_to_llvm_type:
441 * Return the LLVM type corresponding to the regtype C used in instruction
445 regtype_to_llvm_type (char c
)
449 return LLVMInt32Type ();
451 return LLVMInt64Type ();
453 return LLVMDoubleType ();
462 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
465 op_to_llvm_type (int opcode
)
470 return LLVMInt8Type ();
473 return LLVMInt8Type ();
476 return LLVMInt16Type ();
479 return LLVMInt16Type ();
482 return LLVMInt32Type ();
485 return LLVMInt32Type ();
487 return LLVMInt64Type ();
489 return LLVMFloatType ();
491 return LLVMDoubleType ();
493 return LLVMInt64Type ();
495 return LLVMInt32Type ();
497 return LLVMInt64Type ();
500 return LLVMInt8Type ();
503 return LLVMInt16Type ();
506 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
513 return LLVMInt32Type ();
520 return LLVMInt64Type ();
522 printf ("%s\n", mono_inst_name (opcode
));
523 g_assert_not_reached ();
529 * load_store_to_llvm_type:
531 * Return the size/sign/zero extension corresponding to the load/store opcode
535 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
541 case OP_LOADI1_MEMBASE
:
542 case OP_STOREI1_MEMBASE_REG
:
543 case OP_STOREI1_MEMBASE_IMM
:
546 return LLVMInt8Type ();
547 case OP_LOADU1_MEMBASE
:
551 return LLVMInt8Type ();
552 case OP_LOADI2_MEMBASE
:
553 case OP_STOREI2_MEMBASE_REG
:
554 case OP_STOREI2_MEMBASE_IMM
:
557 return LLVMInt16Type ();
558 case OP_LOADU2_MEMBASE
:
562 return LLVMInt16Type ();
563 case OP_LOADI4_MEMBASE
:
564 case OP_LOADU4_MEMBASE
:
567 case OP_STOREI4_MEMBASE_REG
:
568 case OP_STOREI4_MEMBASE_IMM
:
570 return LLVMInt32Type ();
571 case OP_LOADI8_MEMBASE
:
573 case OP_STOREI8_MEMBASE_REG
:
574 case OP_STOREI8_MEMBASE_IMM
:
576 return LLVMInt64Type ();
577 case OP_LOADR4_MEMBASE
:
578 case OP_STORER4_MEMBASE_REG
:
580 return LLVMFloatType ();
581 case OP_LOADR8_MEMBASE
:
582 case OP_STORER8_MEMBASE_REG
:
584 return LLVMDoubleType ();
585 case OP_LOAD_MEMBASE
:
587 case OP_STORE_MEMBASE_REG
:
588 case OP_STORE_MEMBASE_IMM
:
589 *size
= sizeof (gpointer
);
590 return IntPtrType ();
592 g_assert_not_reached ();
600 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
603 ovf_op_to_intrins (int opcode
)
607 return "llvm.sadd.with.overflow.i32";
609 return "llvm.uadd.with.overflow.i32";
611 return "llvm.ssub.with.overflow.i32";
613 return "llvm.usub.with.overflow.i32";
615 return "llvm.smul.with.overflow.i32";
617 return "llvm.umul.with.overflow.i32";
619 return "llvm.sadd.with.overflow.i64";
621 return "llvm.uadd.with.overflow.i64";
623 return "llvm.ssub.with.overflow.i64";
625 return "llvm.usub.with.overflow.i64";
627 return "llvm.smul.with.overflow.i64";
629 return "llvm.umul.with.overflow.i64";
631 g_assert_not_reached ();
637 simd_op_to_intrins (int opcode
)
640 #if defined(TARGET_X86) || defined(TARGET_AMD64)
642 return "llvm.x86.sse2.min.pd";
644 return "llvm.x86.sse.min.ps";
646 return "llvm.x86.sse41.pminud";
648 return "llvm.x86.sse41.pminuw";
650 return "llvm.x86.sse2.pminu.b";
652 return "llvm.x86.sse2.pmins.w";
654 return "llvm.x86.sse2.max.pd";
656 return "llvm.x86.sse.max.ps";
658 return "llvm.x86.sse3.hadd.pd";
660 return "llvm.x86.sse3.hadd.ps";
662 return "llvm.x86.sse3.hsub.pd";
664 return "llvm.x86.sse3.hsub.ps";
666 return "llvm.x86.sse41.pmaxud";
668 return "llvm.x86.sse41.pmaxuw";
670 return "llvm.x86.sse2.pmaxu.b";
672 return "llvm.x86.sse3.addsub.ps";
674 return "llvm.x86.sse3.addsub.pd";
675 case OP_EXTRACT_MASK
:
676 return "llvm.x86.sse2.pmovmskb.128";
679 return "llvm.x86.sse2.psrli.w";
682 return "llvm.x86.sse2.psrli.d";
685 return "llvm.x86.sse2.psrli.q";
688 return "llvm.x86.sse2.pslli.w";
691 return "llvm.x86.sse2.pslli.d";
694 return "llvm.x86.sse2.pslli.q";
697 return "llvm.x86.sse2.psrai.w";
700 return "llvm.x86.sse2.psrai.d";
702 return "llvm.x86.sse2.padds.b";
704 return "llvm.x86.sse2.padds.w";
706 return "llvm.x86.sse2.psubs.b";
708 return "llvm.x86.sse2.psubs.w";
709 case OP_PADDB_SAT_UN
:
710 return "llvm.x86.sse2.paddus.b";
711 case OP_PADDW_SAT_UN
:
712 return "llvm.x86.sse2.paddus.w";
713 case OP_PSUBB_SAT_UN
:
714 return "llvm.x86.sse2.psubus.b";
715 case OP_PSUBW_SAT_UN
:
716 return "llvm.x86.sse2.psubus.w";
718 return "llvm.x86.sse2.pavg.b";
720 return "llvm.x86.sse2.pavg.w";
722 return "llvm.x86.sse.sqrt.ps";
724 return "llvm.x86.sse2.sqrt.pd";
726 return "llvm.x86.sse.rsqrt.ps";
728 return "llvm.x86.sse.rcp.ps";
730 return "llvm.x86.sse2.pcmpeq.b";
732 return "llvm.x86.sse2.pcmpeq.w";
734 return "llvm.x86.sse2.pcmpeq.d";
736 return "llvm.x86.sse41.pcmpeqq";
738 return "llvm.x86.sse2.pcmpgt.b";
740 return "llvm.x86.sse2.cvtdq2pd";
742 return "llvm.x86.sse2.cvtdq2ps";
744 return "llvm.x86.sse2.cvtpd2dq";
746 return "llvm.x86.sse2.cvtps2dq";
748 return "llvm.x86.sse2.cvtpd2ps";
750 return "llvm.x86.sse2.cvtps2pd";
752 return "llvm.x86.sse2.cvttpd2dq";
754 return "llvm.x86.sse2.cvttps2dq";
756 return "llvm.x86.sse.cmp.ps";
758 return "llvm.x86.sse2.cmp.pd";
760 return "llvm.x86.sse2.packsswb.128";
762 return "llvm.x86.sse2.packssdw.128";
764 return "llvm.x86.sse2.packuswb.128";
766 return "llvm.x86.sse41.packusdw";
768 return "llvm.x86.sse2.pmulh.w";
769 case OP_PMULW_HIGH_UN
:
770 return "llvm.x86.sse2.pmulhu.w";
773 g_assert_not_reached ();
779 simd_op_to_llvm_type (int opcode
)
781 #if defined(TARGET_X86) || defined(TARGET_AMD64)
785 return type_to_simd_type (MONO_TYPE_R8
);
788 return type_to_simd_type (MONO_TYPE_I8
);
791 return type_to_simd_type (MONO_TYPE_I4
);
796 return type_to_simd_type (MONO_TYPE_I2
);
800 return type_to_simd_type (MONO_TYPE_I1
);
802 return type_to_simd_type (MONO_TYPE_R4
);
805 return type_to_simd_type (MONO_TYPE_I4
);
809 return type_to_simd_type (MONO_TYPE_R8
);
813 return type_to_simd_type (MONO_TYPE_R4
);
814 case OP_EXTRACT_MASK
:
815 return type_to_simd_type (MONO_TYPE_I1
);
821 return type_to_simd_type (MONO_TYPE_R4
);
824 return type_to_simd_type (MONO_TYPE_R8
);
826 g_assert_not_reached ();
837 * Return the LLVM basic block corresponding to BB.
839 static LLVMBasicBlockRef
840 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
844 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
845 sprintf (bb_name
, "BB%d", bb
->block_num
);
847 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
848 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
851 return ctx
->bblocks
[bb
->block_num
].bblock
;
857 * Return the last LLVM bblock corresponding to BB.
858 * This might not be equal to the bb returned by get_bb () since we need to generate
859 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
861 static LLVMBasicBlockRef
862 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
865 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
868 static LLVMBasicBlockRef
869 gen_bb (EmitContext
*ctx
, const char *prefix
)
873 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
874 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
880 * Return the target of the patch identified by TYPE and TARGET.
883 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
887 memset (&ji
, 0, sizeof (ji
));
889 ji
.data
.target
= target
;
891 return mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
);
897 * Emit code to convert the LLVM value V to DTYPE.
900 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
902 LLVMTypeRef stype
= LLVMTypeOf (v
);
904 if (stype
!= dtype
) {
905 gboolean ext
= FALSE
;
908 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
910 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
912 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
916 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
918 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
919 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
922 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
923 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
924 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
925 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
926 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
927 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
928 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
929 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
931 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
932 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
933 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
934 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
935 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
936 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
938 #ifdef MONO_ARCH_SOFT_FLOAT
939 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
940 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
941 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
942 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
945 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
946 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
949 LLVMDumpValue (LLVMConstNull (dtype
));
950 g_assert_not_reached ();
958 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
960 return convert_full (ctx
, v
, dtype
, FALSE
);
964 * emit_volatile_load:
966 * If vreg is volatile, emit a load from its address.
969 emit_volatile_load (EmitContext
*ctx
, int vreg
)
973 LLVMValueRef v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
974 t
= ctx
->vreg_cli_types
[vreg
];
975 if (t
&& !t
->byref
) {
977 * Might have to zero extend since llvm doesn't have
980 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
981 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
982 else if (t
->type
== MONO_TYPE_U8
)
983 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
990 * emit_volatile_store:
992 * If VREG is volatile, emit a store from its value to its address.
995 emit_volatile_store (EmitContext
*ctx
, int vreg
)
997 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
999 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1000 g_assert (ctx
->addresses
[vreg
]);
1001 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1007 * Maps parameter indexes in the original signature to parameter indexes
1008 * in the LLVM signature.
1011 /* The indexes of various special arguments in the LLVM signature */
1012 int vret_arg_pindex
, this_arg_pindex
, rgctx_arg_pindex
, imt_arg_pindex
;
1016 * sig_to_llvm_sig_full:
1018 * Return the LLVM signature corresponding to the mono signature SIG using the
1019 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1022 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
,
1025 LLVMTypeRef ret_type
;
1026 LLVMTypeRef
*param_types
= NULL
;
1028 int i
, j
, pindex
, vret_arg_pindex
= 0;
1030 gboolean vretaddr
= FALSE
;
1033 memset (sinfo
, 0, sizeof (LLVMSigInfo
));
1035 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
1036 CHECK_FAILURE (ctx
);
1038 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
1039 /* LLVM models this by returning an aggregate value */
1040 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1041 LLVMTypeRef members
[2];
1043 members
[0] = IntPtrType ();
1044 ret_type
= LLVMStructType (members
, 1, FALSE
);
1046 g_assert_not_reached ();
1048 } else if (cinfo
&& MONO_TYPE_ISSTRUCT (sig
->ret
)) {
1049 g_assert (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
);
1051 ret_type
= LLVMVoidType ();
1054 pindexes
= g_new0 (int, sig
->param_count
);
1055 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 2) + 3);
1057 if (cinfo
&& cinfo
->rgctx_arg
) {
1059 sinfo
->rgctx_arg_pindex
= pindex
;
1060 param_types
[pindex
] = IntPtrType ();
1063 if (cinfo
&& cinfo
->imt_arg
&& IS_LLVM_MONO_BRANCH
) {
1065 sinfo
->imt_arg_pindex
= pindex
;
1066 param_types
[pindex
] = IntPtrType ();
1070 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1071 vret_arg_pindex
= pindex
;
1072 if (cinfo
->vret_arg_index
== 1) {
1073 /* Add the slots consumed by the first argument */
1074 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1075 switch (ainfo
->storage
) {
1076 case LLVMArgVtypeInReg
:
1077 for (j
= 0; j
< 2; ++j
) {
1078 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1088 sinfo
->vret_arg_pindex
= vret_arg_pindex
;
1091 if (vretaddr
&& vret_arg_pindex
== pindex
)
1092 param_types
[pindex
++] = IntPtrType ();
1095 sinfo
->this_arg_pindex
= pindex
;
1096 param_types
[pindex
++] = IntPtrType ();
1098 if (vretaddr
&& vret_arg_pindex
== pindex
)
1099 param_types
[pindex
++] = IntPtrType ();
1100 for (i
= 0; i
< sig
->param_count
; ++i
) {
1101 if (vretaddr
&& vret_arg_pindex
== pindex
)
1102 param_types
[pindex
++] = IntPtrType ();
1103 pindexes
[i
] = pindex
;
1104 if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeInReg
) {
1105 for (j
= 0; j
< 2; ++j
) {
1106 switch (cinfo
->args
[i
+ sig
->hasthis
].pair_storage
[j
]) {
1108 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
1113 g_assert_not_reached ();
1116 } else if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
) {
1117 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1118 CHECK_FAILURE (ctx
);
1119 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1122 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1125 if (vretaddr
&& vret_arg_pindex
== pindex
)
1126 param_types
[pindex
++] = IntPtrType ();
1128 CHECK_FAILURE (ctx
);
1130 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1131 g_free (param_types
);
1134 sinfo
->pindexes
= pindexes
;
1142 g_free (param_types
);
1148 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1150 return sig_to_llvm_sig_full (ctx
, sig
, NULL
, NULL
);
1154 * LLVMFunctionType1:
1156 * Create an LLVM function type from the arguments.
1158 static G_GNUC_UNUSED LLVMTypeRef
1159 LLVMFunctionType1(LLVMTypeRef ReturnType
,
1160 LLVMTypeRef ParamType1
,
1163 LLVMTypeRef param_types
[1];
1165 param_types
[0] = ParamType1
;
1167 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1171 * LLVMFunctionType2:
1173 * Create an LLVM function type from the arguments.
1176 LLVMFunctionType2(LLVMTypeRef ReturnType
,
1177 LLVMTypeRef ParamType1
,
1178 LLVMTypeRef ParamType2
,
1181 LLVMTypeRef param_types
[2];
1183 param_types
[0] = ParamType1
;
1184 param_types
[1] = ParamType2
;
1186 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1190 * LLVMFunctionType3:
1192 * Create an LLVM function type from the arguments.
1195 LLVMFunctionType3(LLVMTypeRef ReturnType
,
1196 LLVMTypeRef ParamType1
,
1197 LLVMTypeRef ParamType2
,
1198 LLVMTypeRef ParamType3
,
1201 LLVMTypeRef param_types
[3];
1203 param_types
[0] = ParamType1
;
1204 param_types
[1] = ParamType2
;
1205 param_types
[2] = ParamType3
;
1207 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1213 * Create an LLVM builder and remember it so it can be freed later.
1215 static LLVMBuilderRef
1216 create_builder (EmitContext
*ctx
)
1218 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1220 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1226 get_plt_entry (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1228 char *callee_name
= mono_aot_get_plt_symbol (type
, data
);
1229 LLVMValueRef callee
;
1234 if (ctx
->cfg
->compile_aot
)
1235 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1236 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1239 callee
= g_hash_table_lookup (ctx
->lmodule
->plt_entries
, callee_name
);
1241 callee
= LLVMAddFunction (ctx
->module
, callee_name
, llvm_sig
);
1243 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1245 g_hash_table_insert (ctx
->lmodule
->plt_entries
, (char*)callee_name
, callee
);
1252 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1254 MonoMethodHeader
*header
= cfg
->header
;
1255 MonoExceptionClause
*clause
;
1259 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1260 return (bb
->region
>> 8) - 1;
1263 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1264 clause
= &header
->clauses
[i
];
1266 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1274 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1276 LLVMValueRef md_arg
;
1279 if (!IS_LLVM_MONO_BRANCH
)
1282 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1283 md_arg
= LLVMMDString ("mono", 4);
1284 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1290 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1294 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1296 MonoCompile
*cfg
= ctx
->cfg
;
1298 LLVMBuilderRef builder
= *builder_ref
;
1301 clause_index
= get_handler_clause (cfg
, bb
);
1303 if (clause_index
!= -1) {
1304 MonoMethodHeader
*header
= cfg
->header
;
1305 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1306 MonoBasicBlock
*tblock
;
1307 LLVMBasicBlockRef ex_bb
, noex_bb
;
1310 * Have to use an invoke instead of a call, branching to the
1311 * handler bblock of the clause containing this bblock.
1314 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1316 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1319 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1321 ex_bb
= get_bb (ctx
, tblock
);
1323 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1326 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1328 builder
= ctx
->builder
= create_builder (ctx
);
1329 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1331 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1333 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1334 ctx
->builder
= builder
;
1337 *builder_ref
= ctx
->builder
;
1343 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
1345 const char *intrins_name
;
1346 LLVMValueRef args
[16], res
;
1347 LLVMTypeRef addr_type
;
1349 if (is_faulting
&& bb
->region
!= -1 && IS_LLVM_MONO_BRANCH
) {
1351 * We handle loads which can fault by calling a mono specific intrinsic
1352 * using an invoke, so they are handled properly inside try blocks.
1353 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1354 * are marked with IntrReadArgMem.
1358 intrins_name
= "llvm.mono.load.i8.p0i8";
1361 intrins_name
= "llvm.mono.load.i16.p0i16";
1364 intrins_name
= "llvm.mono.load.i32.p0i32";
1367 intrins_name
= "llvm.mono.load.i64.p0i64";
1370 g_assert_not_reached ();
1373 addr_type
= LLVMTypeOf (addr
);
1374 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1375 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1378 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1379 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1380 res
= emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 3);
1382 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1383 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1384 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1385 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1392 * We emit volatile loads for loads which can fault, because otherwise
1393 * LLVM will generate invalid code when encountering a load from a
1396 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1398 /* Mark it with a custom metadata */
1401 set_metadata_flag (res, "mono.faulting.load");
1409 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, gboolean is_faulting
)
1411 const char *intrins_name
;
1412 LLVMValueRef args
[16];
1414 if (is_faulting
&& bb
->region
!= -1 && IS_LLVM_MONO_BRANCH
) {
1417 intrins_name
= "llvm.mono.store.i8.p0i8";
1420 intrins_name
= "llvm.mono.store.i16.p0i16";
1423 intrins_name
= "llvm.mono.store.i32.p0i32";
1426 intrins_name
= "llvm.mono.store.i64.p0i64";
1429 g_assert_not_reached ();
1432 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
1433 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
1434 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1439 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1440 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1441 emit_call (ctx
, bb
, builder_ref
, LLVMGetNamedFunction (ctx
->module
, intrins_name
), args
, 4);
1443 LLVMBuildStore (*builder_ref
, value
, addr
);
1448 * emit_cond_system_exception:
1450 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1451 * Might set the ctx exception.
1454 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
1456 LLVMBasicBlockRef ex_bb
, noex_bb
;
1457 LLVMBuilderRef builder
;
1458 MonoClass
*exc_class
;
1459 LLVMValueRef args
[2];
1461 ex_bb
= gen_bb (ctx
, "EX_BB");
1462 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1464 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
1466 exc_class
= mono_class_from_name (mono_get_corlib (), "System", exc_type
);
1467 g_assert (exc_class
);
1469 /* Emit exception throwing code */
1470 builder
= create_builder (ctx
);
1471 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
1473 if (!ctx
->lmodule
->throw_corlib_exception
) {
1474 LLVMValueRef callee
;
1476 const char *icall_name
;
1478 MonoMethodSignature
*throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 2);
1479 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
1480 throw_sig
->params
[0] = &mono_get_int32_class ()->byval_arg
;
1481 if (IS_LLVM_MONO_BRANCH
) {
1482 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
1483 throw_sig
->params
[1] = &mono_get_intptr_class ()->byval_arg
;
1485 icall_name
= "llvm_throw_corlib_exception_trampoline";
1486 throw_sig
->params
[1] = &mono_get_int32_class ()->byval_arg
;
1488 sig
= sig_to_llvm_sig (ctx
, throw_sig
);
1490 if (ctx
->cfg
->compile_aot
) {
1491 callee
= get_plt_entry (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
1493 callee
= LLVMAddFunction (ctx
->module
, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx
, throw_sig
));
1496 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1497 * - On x86, LLVM generated code doesn't push the arguments
1498 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1499 * arguments, not a pc offset.
1501 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
1504 mono_memory_barrier ();
1505 ctx
->lmodule
->throw_corlib_exception
= callee
;
1509 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
1511 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
, FALSE
);
1513 if (IS_LLVM_MONO_BRANCH
) {
1515 * The LLVM mono branch contains changes so a block address can be passed as an
1516 * argument to a call.
1518 args
[1] = LLVMBuildPtrToInt (builder
, LLVMBlockAddress (ctx
->lmethod
, ex_bb
), IntPtrType (), "");
1519 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1522 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1523 * otherwise only the line numbers in stack traces are incorrect.
1525 if (bb
->region
!= -1 && !IS_LLVM_MONO_BRANCH
)
1526 LLVM_FAILURE (ctx
, "system-ex-in-region");
1528 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1529 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1532 LLVMBuildUnreachable (builder
);
1534 ctx
->builder
= create_builder (ctx
);
1535 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1537 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1547 * emit_reg_to_vtype:
1549 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1552 emit_reg_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
)
1556 size
= get_vtype_size (t
);
1558 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1559 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1562 for (j
= 0; j
< 2; ++j
) {
1563 LLVMValueRef index
[2], addr
;
1564 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1565 LLVMTypeRef part_type
;
1567 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1570 part_type
= LLVMIntType (part_size
* 8);
1571 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1572 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1573 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1575 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1576 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1577 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1579 switch (ainfo
->pair_storage
[j
]) {
1581 LLVMBuildStore (builder
, convert (ctx
, regs
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
1586 g_assert_not_reached ();
1589 size
-= sizeof (gpointer
);
1594 * emit_vtype_to_reg:
1596 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1597 * into REGS, and the number of registers into NREGS.
1600 emit_vtype_to_reg (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
, guint32
*nregs
)
1605 size
= get_vtype_size (t
);
1607 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1608 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1611 for (j
= 0; j
< 2; ++j
) {
1612 LLVMValueRef index
[2], addr
;
1613 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1615 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1618 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1619 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1620 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1622 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1623 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1624 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1626 switch (ainfo
->pair_storage
[j
]) {
1628 regs
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
1633 g_assert_not_reached ();
1635 size
-= sizeof (gpointer
);
1642 build_alloca (EmitContext
*ctx
, MonoType
*t
)
1644 MonoClass
*k
= mono_class_from_mono_type (t
);
1647 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
1650 align
= mono_class_min_align (k
);
1652 /* Sometimes align is not a power of 2 */
1653 while (mono_is_power_of_two (align
) == -1)
1657 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1658 * get executed every time control reaches them.
1660 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
1662 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, type_to_llvm_type (ctx
, t
), NULL
, align
, "");
1663 return ctx
->last_alloca
;
1667 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1670 mark_as_used (LLVMModuleRef module
, LLVMValueRef global
)
1672 LLVMTypeRef used_type
;
1673 LLVMValueRef used
, used_elem
;
1675 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1676 used
= LLVMAddGlobal (module
, used_type
, "llvm.used");
1677 used_elem
= LLVMConstBitCast (global
, LLVMPointerType (LLVMInt8Type (), 0));
1678 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem
, 1));
1679 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
1680 LLVMSetSection (used
, "llvm.metadata");
1686 * Emit code to load/convert arguments.
1689 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
1692 MonoCompile
*cfg
= ctx
->cfg
;
1693 MonoMethodSignature
*sig
= ctx
->sig
;
1694 LLVMCallInfo
*linfo
= ctx
->linfo
;
1697 ctx
->alloca_builder
= create_builder (ctx
);
1700 * Handle indirect/volatile variables by allocating memory for them
1701 * using 'alloca', and storing their address in a temporary.
1703 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
1704 MonoInst
*var
= cfg
->varinfo
[i
];
1707 if (var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) || MONO_TYPE_ISSTRUCT (var
->inst_vtype
)) {
1708 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
1709 CHECK_FAILURE (ctx
);
1710 /* Could be already created by an OP_VPHI */
1711 if (!ctx
->addresses
[var
->dreg
])
1712 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
1713 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
1717 for (i
= 0; i
< sig
->param_count
; ++i
) {
1718 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
1719 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
1721 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
1722 LLVMValueRef regs
[2];
1725 * Emit code to save the argument from the registers to
1726 * the real argument.
1728 pindex
= ctx
->pindexes
[i
];
1729 regs
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
1730 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
1731 regs
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
1735 ctx
->addresses
[reg
] = build_alloca (ctx
, sig
->params
[i
]);
1737 emit_reg_to_vtype (ctx
, builder
, sig
->params
[i
], ctx
->addresses
[reg
], ainfo
, regs
);
1739 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1740 /* Treat these as normal values */
1741 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1743 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
1744 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, ctx
->pindexes
[i
]);
1746 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1747 /* Treat these as normal values */
1748 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1751 ctx
->values
[reg
] = convert (ctx
, ctx
->values
[reg
], llvm_type_to_stack_type (type_to_llvm_type (ctx
, sig
->params
[i
])));
1756 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
1758 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
1759 for (i
= 0; i
< sig
->param_count
; ++i
)
1760 if (!MONO_TYPE_ISSTRUCT (sig
->params
[i
]))
1761 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
1763 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->generic_sharing_context
) {
1764 LLVMValueRef this_alloc
;
1767 * The exception handling code needs the location where the this argument was
1768 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1769 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1770 * location into the LSDA.
1772 this_alloc
= mono_llvm_build_alloca (builder
, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
1773 /* This volatile store will keep the alloca alive */
1774 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
);
1776 set_metadata_flag (this_alloc
, "mono.this");
1779 if (cfg
->rgctx_var
) {
1780 LLVMValueRef rgctx_alloc
, store
;
1783 * We handle the rgctx arg similarly to the this pointer.
1785 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
1786 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
1787 /* This volatile store will keep the alloca alive */
1788 store
= mono_llvm_build_store (builder
, ctx
->rgctx_arg
, rgctx_alloc
, TRUE
);
1790 set_metadata_flag (rgctx_alloc
, "mono.this");
1794 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1795 * it needs to continue normally, or return back to the exception handling system.
1797 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1798 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
))
1799 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
1800 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
) && bb
->in_scount
== 0) {
1804 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
1805 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
1806 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
1808 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
1811 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1812 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1813 * LLVM optimizer passes.
1815 sprintf (name
, "BB_%d_CALL_HANDLER_TARGET", bb
->block_num
);
1816 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
1824 /* Have to export this for AOT */
1826 mono_personality (void);
1829 mono_personality (void)
1832 g_assert_not_reached ();
1836 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
1838 MonoCompile
*cfg
= ctx
->cfg
;
1839 LLVMModuleRef module
= ctx
->module
;
1840 LLVMValueRef
*values
= ctx
->values
;
1841 LLVMValueRef
*addresses
= ctx
->addresses
;
1842 MonoCallInst
*call
= (MonoCallInst
*)ins
;
1843 MonoMethodSignature
*sig
= call
->signature
;
1844 LLVMValueRef callee
, lcall
;
1846 LLVMCallInfo
*cinfo
;
1850 LLVMTypeRef llvm_sig
;
1852 gboolean
virtual, calli
;
1853 LLVMBuilderRef builder
= *builder_ref
;
1856 if (call
->signature
->call_convention
!= MONO_CALL_DEFAULT
)
1857 LLVM_FAILURE (ctx
, "non-default callconv");
1859 if (call
->rgctx_arg_reg
&& !IS_LLVM_MONO_BRANCH
)
1860 LLVM_FAILURE (ctx
, "rgctx reg in call");
1862 if (call
->rgctx_reg
&& !IS_LLVM_MONO_BRANCH
) {
1864 * It might be possible to support this by creating a static rgctx trampoline, but
1865 * common_call_trampoline () would patch callsites to call the trampoline, which
1866 * would be incorrect if the rgctx arg is computed dynamically.
1868 LLVM_FAILURE (ctx
, "rgctx reg");
1871 cinfo
= call
->cinfo
;
1872 if (call
->rgctx_arg_reg
)
1873 cinfo
->rgctx_arg
= TRUE
;
1874 if (call
->imt_arg_reg
)
1875 cinfo
->imt_arg
= TRUE
;
1877 vretaddr
= cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
;
1879 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
, &sinfo
);
1880 CHECK_FAILURE (ctx
);
1882 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
);
1883 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
);
1885 /* FIXME: Avoid creating duplicate methods */
1887 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
1891 if (cfg
->compile_aot
) {
1892 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
1894 LLVM_FAILURE (ctx
, "can't encode patch");
1896 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1899 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1901 LLVMAddGlobalMapping (ee
, callee
, target
);
1906 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
1912 memset (&ji, 0, sizeof (ji));
1913 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1914 ji.data.target = info->name;
1916 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1918 if (cfg
->compile_aot
) {
1919 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
1921 LLVM_FAILURE (ctx
, "can't encode patch");
1923 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1924 target
= (gpointer
)mono_icall_get_wrapper (info
);
1925 LLVMAddGlobalMapping (ee
, callee
, target
);
1928 if (cfg
->compile_aot
) {
1930 if (cfg
->abs_patches
) {
1931 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1933 callee
= get_plt_entry (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
1935 LLVM_FAILURE (ctx
, "can't encode patch");
1939 LLVM_FAILURE (ctx
, "aot");
1941 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1943 if (cfg
->abs_patches
) {
1944 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
1947 * FIXME: Some trampolines might have
1948 * their own calling convention on some platforms.
1950 #ifndef TARGET_AMD64
1951 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
)
1952 LLVM_FAILURE (ctx
, "trampoline with own cconv");
1954 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
);
1955 LLVMAddGlobalMapping (ee
, callee
, target
);
1959 LLVMAddGlobalMapping (ee
, callee
, (gpointer
)call
->fptr
);
1965 int size
= sizeof (gpointer
);
1968 g_assert (ins
->inst_offset
% size
== 0);
1969 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
1972 * When using the llvm mono branch, we can support IMT directly, otherwise
1973 * we need to call a trampoline.
1975 if (call
->method
&& call
->method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
&& !IS_LLVM_MONO_BRANCH
) {
1976 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1977 if (cfg
->compile_aot
) {
1978 MonoJumpInfoImtTramp
*imt_tramp
= g_new0 (MonoJumpInfoImtTramp
, 1);
1979 imt_tramp
->method
= call
->method
;
1980 imt_tramp
->vt_offset
= call
->inst
.inst_offset
;
1982 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE
, imt_tramp
);
1984 callee
= LLVMAddFunction (module
, "", llvm_sig
);
1985 target
= mono_create_llvm_imt_trampoline (cfg
->domain
, call
->method
, call
->inst
.inst_offset
);
1986 LLVMAddGlobalMapping (ee
, callee
, target
);
1989 /* No support for passing the IMT argument */
1990 LLVM_FAILURE (ctx
, "imt");
1993 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
1996 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
1998 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
2003 * Collect and convert arguments
2005 len
= sizeof (LLVMValueRef
) * ((sig
->param_count
* 2) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
);
2006 args
= alloca (len
);
2007 memset (args
, 0, len
);
2008 l
= call
->out_ireg_args
;
2010 if (IS_LLVM_MONO_BRANCH
) {
2011 if (call
->rgctx_arg_reg
) {
2012 g_assert (values
[call
->rgctx_arg_reg
]);
2013 args
[sinfo
.rgctx_arg_pindex
] = values
[call
->rgctx_arg_reg
];
2015 if (call
->imt_arg_reg
) {
2016 g_assert (values
[call
->imt_arg_reg
]);
2017 args
[sinfo
.imt_arg_pindex
] = values
[call
->imt_arg_reg
];
2022 if (!addresses
[call
->inst
.dreg
])
2023 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
2024 args
[sinfo
.vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
2027 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
2030 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
] : NULL
;
2034 pindex
= sinfo
.this_arg_pindex
;
2036 pindex
= sinfo
.pindexes
[i
- 1];
2038 pindex
= sinfo
.pindexes
[i
];
2041 regpair
= (guint32
)(gssize
)(l
->data
);
2042 reg
= regpair
& 0xffffff;
2043 args
[pindex
] = values
[reg
];
2044 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2046 LLVMValueRef regs
[2];
2051 g_assert (addresses
[reg
]);
2053 emit_vtype_to_reg (ctx
, builder
, sig
->params
[i
- sig
->hasthis
], addresses
[reg
], ainfo
, regs
, &nregs
);
2054 for (j
= 0; j
< nregs
; ++j
)
2055 args
[pindex
++] = regs
[j
];
2058 // FIXME: Get rid of the VMOVE
2059 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
2060 g_assert (addresses
[reg
]);
2061 args
[pindex
] = addresses
[reg
];
2063 g_assert (args
[pindex
]);
2064 if (i
== 0 && sig
->hasthis
)
2065 args
[pindex
] = convert (ctx
, args
[pindex
], IntPtrType ());
2067 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, sig
->params
[i
- sig
->hasthis
]));
2073 // FIXME: Align call sites
2079 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
2081 #ifdef LLVM_MONO_BRANCH
2083 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2085 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2086 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
2088 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2089 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
2091 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
2093 if (call
->rgctx_arg_reg
)
2094 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.rgctx_arg_pindex
, LLVMInRegAttribute
);
2095 if (call
->imt_arg_reg
)
2096 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.imt_arg_pindex
, LLVMInRegAttribute
);
2099 /* Add byval attributes if needed */
2100 for (i
= 0; i
< sig
->param_count
; ++i
) {
2101 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
+ sig
->hasthis
] : NULL
;
2103 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
) {
2104 LLVMAddInstrAttribute (lcall
, 1 + sinfo
.pindexes
[i
], LLVMByValAttribute
);
2109 * Convert the result
2111 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2112 LLVMValueRef regs
[2];
2114 if (!addresses
[ins
->dreg
])
2115 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
2117 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
2118 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
2119 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
2121 emit_reg_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
2122 } else if (sig
->ret
->type
!= MONO_TYPE_VOID
&& !vretaddr
) {
2123 /* If the method returns an unsigned value, need to zext it */
2125 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
));
2128 *builder_ref
= ctx
->builder
;
2130 g_free (sinfo
.pindexes
);
2138 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
2140 MonoCompile
*cfg
= ctx
->cfg
;
2141 MonoMethodSignature
*sig
= ctx
->sig
;
2142 LLVMValueRef method
= ctx
->lmethod
;
2143 LLVMValueRef
*values
= ctx
->values
;
2144 LLVMValueRef
*addresses
= ctx
->addresses
;
2146 LLVMCallInfo
*linfo
= ctx
->linfo
;
2147 LLVMModuleRef module
= ctx
->module
;
2148 BBInfo
*bblocks
= ctx
->bblocks
;
2150 LLVMBasicBlockRef cbb
;
2151 LLVMBuilderRef builder
;
2152 gboolean has_terminator
;
2154 LLVMValueRef lhs
, rhs
;
2156 cbb
= get_bb (ctx
, bb
);
2157 builder
= create_builder (ctx
);
2158 ctx
->builder
= builder
;
2159 LLVMPositionBuilderAtEnd (builder
, cbb
);
2161 if (bb
== cfg
->bb_entry
)
2162 emit_entry_bb (ctx
, builder
);
2163 CHECK_FAILURE (ctx
);
2165 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
2167 LLVMValueRef eh_selector
, eh_exception
, personality
, args
[4];
2168 LLVMBasicBlockRef target_bb
;
2170 static gint32 mapping_inited
;
2171 static int ti_generator
;
2174 LLVMValueRef type_info
;
2177 if (!bblocks
[bb
->block_num
].invoke_target
) {
2179 * LLVM asserts if llvm.eh.selector is called from a bblock which
2180 * doesn't have an invoke pointing at it.
2181 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2183 LLVM_FAILURE (ctx
, "handler without invokes");
2186 eh_selector
= LLVMGetNamedFunction (module
, eh_selector_name
);
2188 if (cfg
->compile_aot
) {
2189 /* Use a dummy personality function */
2190 personality
= LLVMGetNamedFunction (module
, "mono_aot_personality");
2191 g_assert (personality
);
2193 personality
= LLVMGetNamedFunction (module
, "mono_personality");
2194 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
2195 LLVMAddGlobalMapping (ee
, personality
, mono_personality
);
2198 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
2200 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
2203 * Create the type info
2205 sprintf (ti_name
, "type_info_%d", ti_generator
);
2208 if (cfg
->compile_aot
) {
2209 /* decode_eh_frame () in aot-runtime.c will decode this */
2210 type_info
= LLVMAddGlobal (module
, LLVMInt32Type (), ti_name
);
2211 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
2213 LLVMSetLinkage (type_info
, LLVMPrivateLinkage
);
2214 LLVMSetVisibility (type_info
, LLVMHiddenVisibility
);
2217 * Enabling this causes llc to crash:
2218 * http://llvm.org/bugs/show_bug.cgi?id=6102
2220 //LLVM_FAILURE (ctx, "aot+clauses");
2223 * After the cfg mempool is freed, the type info will point to stale memory,
2224 * but this is not a problem, since we decode it once in exception_cb during
2227 ti
= mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
2228 *(gint32
*)ti
= clause_index
;
2230 type_info
= LLVMAddGlobal (module
, i8ptr
, ti_name
);
2232 LLVMAddGlobalMapping (ee
, type_info
, ti
);
2235 args
[0] = LLVMConstNull (i8ptr
);
2236 args
[1] = LLVMConstBitCast (personality
, i8ptr
);
2237 args
[2] = type_info
;
2238 LLVMBuildCall (builder
, eh_selector
, args
, 3, "");
2240 /* Store the exception into the exvar */
2241 if (bb
->in_scount
== 1) {
2242 g_assert (bb
->in_scount
== 1);
2243 exvar
= bb
->in_stack
[0];
2245 eh_exception
= LLVMGetNamedFunction (module
, "llvm.eh.exception");
2247 // FIXME: This is shared with filter clauses ?
2248 g_assert (!values
[exvar
->dreg
]);
2249 values
[exvar
->dreg
] = LLVMBuildCall (builder
, eh_exception
, NULL
, 0, "");
2250 emit_volatile_store (ctx
, exvar
->dreg
);
2253 /* Start a new bblock which CALL_HANDLER can branch to */
2254 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
2256 LLVMBuildBr (builder
, target_bb
);
2258 ctx
->builder
= builder
= create_builder (ctx
);
2259 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
2261 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
2265 has_terminator
= FALSE
;
2266 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
2267 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
2269 char dname_buf
[128];
2272 /* There could be instructions after a terminator, skip them */
2275 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
2276 sprintf (dname_buf
, "t%d", ins
->dreg
);
2280 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
2281 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
2283 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2284 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
2286 /* It is ok for SETRET to have an uninitialized argument */
2287 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
)
2288 LLVM_FAILURE (ctx
, "sreg1");
2289 lhs
= values
[ins
->sreg1
];
2295 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
2296 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
2297 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
2298 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
2300 if (!values
[ins
->sreg2
])
2301 LLVM_FAILURE (ctx
, "sreg2");
2302 rhs
= values
[ins
->sreg2
];
2308 //mono_print_ins (ins);
2309 switch (ins
->opcode
) {
2312 case OP_LIVERANGE_START
:
2313 case OP_LIVERANGE_END
:
2316 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
2319 #if SIZEOF_VOID_P == 4
2320 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2322 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
2326 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
2329 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
2332 LLVMBuildBr (builder
, get_bb (ctx
, ins
->inst_target_bb
));
2333 has_terminator
= TRUE
;
2339 LLVMBasicBlockRef new_bb
;
2340 LLVMBuilderRef new_builder
;
2342 // The default branch is already handled
2343 // FIXME: Handle it here
2345 /* Start new bblock */
2346 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
2347 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
2349 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2350 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
2351 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
2352 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
2354 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
2357 new_builder
= create_builder (ctx
);
2358 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
2359 LLVMBuildUnreachable (new_builder
);
2361 has_terminator
= TRUE
;
2362 g_assert (!ins
->next
);
2368 if (linfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2369 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
2370 LLVMValueRef part1
, retval
;
2373 size
= get_vtype_size (sig
->ret
);
2375 g_assert (addresses
[ins
->sreg1
]);
2377 g_assert (linfo
->ret
.pair_storage
[0] == LLVMArgInIReg
);
2378 g_assert (linfo
->ret
.pair_storage
[1] == LLVMArgNone
);
2380 part1
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMIntType (size
* 8), 0), ""), ""), IntPtrType ());
2382 retval
= LLVMBuildInsertValue (builder
, LLVMGetUndef (ret_type
), part1
, 0, "");
2384 LLVMBuildRet (builder
, retval
);
2388 if (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
) {
2389 LLVMBuildRetVoid (builder
);
2393 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
2395 * The method did not set its return value, probably because it
2396 * ends with a throw.
2399 LLVMBuildRetVoid (builder
);
2401 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
2403 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
2405 has_terminator
= TRUE
;
2411 case OP_ICOMPARE_IMM
:
2412 case OP_LCOMPARE_IMM
:
2413 case OP_COMPARE_IMM
: {
2417 if (ins
->next
->opcode
== OP_NOP
)
2420 if (ins
->next
->opcode
== OP_BR
)
2421 /* The comparison result is not needed */
2424 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
2426 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
2427 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2428 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2430 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2431 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2432 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2434 if (ins
->opcode
== OP_LCOMPARE
) {
2435 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2436 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
2438 if (ins
->opcode
== OP_ICOMPARE
) {
2439 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2440 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2444 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2445 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
2446 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
2447 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
2450 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2451 if (ins
->opcode
== OP_FCOMPARE
)
2452 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2453 else if (ins
->opcode
== OP_COMPARE_IMM
)
2454 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
2455 else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2456 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
2457 /* The immediate is encoded in two fields */
2458 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
2459 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
2461 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
2464 else if (ins
->opcode
== OP_COMPARE
)
2465 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
2467 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
2469 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
2470 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
2471 has_terminator
= TRUE
;
2472 } else if (MONO_IS_SETCC (ins
->next
)) {
2473 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
2475 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2477 /* Add stores for volatile variables */
2478 emit_volatile_store (ctx
, ins
->next
->dreg
);
2479 } else if (MONO_IS_COND_EXC (ins
->next
)) {
2480 emit_cond_system_exception (ctx
, bb
, ins
->next
->inst_p1
, cmp
);
2481 CHECK_FAILURE (ctx
);
2482 builder
= ctx
->builder
;
2484 LLVM_FAILURE (ctx
, "next");
2498 rel
= mono_opcode_to_cond (ins
->opcode
);
2500 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2501 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2509 gboolean empty
= TRUE
;
2511 /* Check that all input bblocks really branch to us */
2512 for (i
= 0; i
< bb
->in_count
; ++i
) {
2513 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
2514 ins
->inst_phi_args
[i
+ 1] = -1;
2520 /* LLVM doesn't like phi instructions with zero operands */
2521 ctx
->is_dead
[ins
->dreg
] = TRUE
;
2525 /* Created earlier, insert it now */
2526 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
2528 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
2529 int sreg1
= ins
->inst_phi_args
[i
+ 1];
2533 * Count the number of times the incoming bblock branches to us,
2534 * since llvm requires a separate entry for each.
2536 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
2537 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
2540 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
2541 if (switch_ins
->inst_many_bb
[j
] == bb
)
2548 /* Remember for later */
2549 for (j
= 0; j
< count
; ++j
) {
2550 PhiNode
*node
= mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
2553 node
->in_bb
= bb
->in_bb
[i
];
2555 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
);
2565 values
[ins
->dreg
] = lhs
;
2568 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
2571 values
[ins
->dreg
] = lhs
;
2573 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
2575 * This is added by the spilling pass in case of the JIT,
2576 * but we have to do it ourselves.
2578 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
2612 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2613 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2615 switch (ins
->opcode
) {
2618 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
2622 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
2626 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
2630 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
2634 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
2638 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
2642 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
2645 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
2649 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
2653 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
2657 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
2661 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
2665 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
2669 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
2673 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
2676 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
2679 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
2683 g_assert_not_reached ();
2690 case OP_IREM_UN_IMM
:
2692 case OP_IDIV_UN_IMM
:
2698 case OP_ISHR_UN_IMM
:
2707 case OP_LSHR_UN_IMM
:
2715 if (spec
[MONO_INST_SRC1
] == 'l') {
2716 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2718 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2721 #if SIZEOF_VOID_P == 4
2722 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
2723 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2726 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2727 lhs
= convert (ctx
, lhs
, IntPtrType ());
2728 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
2729 switch (ins
->opcode
) {
2733 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
2737 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
2741 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
2745 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
2747 case OP_IDIV_UN_IMM
:
2748 case OP_LDIV_UN_IMM
:
2749 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
2753 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
2755 case OP_IREM_UN_IMM
:
2756 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
2761 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
2765 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
2769 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
2774 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
2779 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
2781 case OP_ISHR_UN_IMM
:
2782 /* This is used to implement conv.u4, so the lhs could be an i8 */
2783 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2784 imm
= convert (ctx
, imm
, LLVMInt32Type ());
2785 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2787 case OP_LSHR_UN_IMM
:
2788 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2791 g_assert_not_reached ();
2796 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
2799 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
2802 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
2803 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
2806 guint32 v
= 0xffffffff;
2807 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), lhs
, dname
);
2811 guint64 v
= 0xffffffffffffffffLL
;
2812 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
2815 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2817 LLVMValueRef v1
, v2
;
2819 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
2820 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
2821 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
2826 case OP_ICONV_TO_I1
:
2827 case OP_ICONV_TO_I2
:
2828 case OP_ICONV_TO_I4
:
2829 case OP_ICONV_TO_U1
:
2830 case OP_ICONV_TO_U2
:
2831 case OP_ICONV_TO_U4
:
2832 case OP_LCONV_TO_I1
:
2833 case OP_LCONV_TO_I2
:
2834 case OP_LCONV_TO_U1
:
2835 case OP_LCONV_TO_U2
:
2836 case OP_LCONV_TO_U4
: {
2839 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
);
2841 /* Have to do two casts since our vregs have type int */
2842 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
2844 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
2846 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
2849 case OP_ICONV_TO_I8
:
2850 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2852 case OP_ICONV_TO_U8
:
2853 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2855 case OP_FCONV_TO_I4
:
2856 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
2858 case OP_FCONV_TO_I1
:
2859 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2861 case OP_FCONV_TO_U1
:
2862 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2864 case OP_FCONV_TO_I2
:
2865 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2867 case OP_FCONV_TO_U2
:
2868 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2870 case OP_FCONV_TO_I8
:
2871 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
2874 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
2876 case OP_ICONV_TO_R8
:
2877 case OP_LCONV_TO_R8
:
2878 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2880 case OP_LCONV_TO_R_UN
:
2881 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2883 #if SIZEOF_VOID_P == 4
2886 case OP_LCONV_TO_I4
:
2887 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2889 case OP_ICONV_TO_R4
:
2890 case OP_LCONV_TO_R4
:
2891 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
2892 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2894 case OP_FCONV_TO_R4
:
2895 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
2896 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2899 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2902 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2905 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2907 case OP_LOCALLOC_IMM
: {
2910 guint32 size
= ins
->inst_imm
;
2911 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
2913 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
2915 if (ins
->flags
& MONO_INST_INIT
) {
2916 LLVMValueRef args
[5];
2919 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2920 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
2921 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2922 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2923 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2926 values
[ins
->dreg
] = v
;
2930 LLVMValueRef v
, size
;
2932 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
), "");
2934 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
2936 if (ins
->flags
& MONO_INST_INIT
) {
2937 LLVMValueRef args
[5];
2940 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2942 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2943 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2944 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2946 values
[ins
->dreg
] = v
;
2950 case OP_LOADI1_MEMBASE
:
2951 case OP_LOADU1_MEMBASE
:
2952 case OP_LOADI2_MEMBASE
:
2953 case OP_LOADU2_MEMBASE
:
2954 case OP_LOADI4_MEMBASE
:
2955 case OP_LOADU4_MEMBASE
:
2956 case OP_LOADI8_MEMBASE
:
2957 case OP_LOADR4_MEMBASE
:
2958 case OP_LOADR8_MEMBASE
:
2959 case OP_LOAD_MEMBASE
:
2967 LLVMValueRef base
, index
, addr
;
2969 gboolean sext
= FALSE
, zext
= FALSE
;
2970 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
2972 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2977 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
)) {
2978 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
2983 if (ins
->inst_offset
== 0) {
2985 } else if (ins
->inst_offset
% size
!= 0) {
2986 /* Unaligned load */
2987 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2988 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
2990 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2991 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
2995 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
2997 values
[ins
->dreg
] = emit_load (ctx
, bb
, &builder
, size
, addr
, dname
, is_volatile
);
2999 if (!is_volatile
&& (ins
->flags
& MONO_INST_CONSTANT_LOAD
)) {
3001 * These will signal LLVM that these loads do not alias any stores, and
3002 * they can't fail, allowing them to be hoisted out of loops.
3004 set_metadata_flag (values
[ins
->dreg
], "mono.noalias");
3005 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
3009 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
3011 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
3012 else if (ins
->opcode
== OP_LOADR4_MEMBASE
)
3013 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
3017 case OP_STOREI1_MEMBASE_REG
:
3018 case OP_STOREI2_MEMBASE_REG
:
3019 case OP_STOREI4_MEMBASE_REG
:
3020 case OP_STOREI8_MEMBASE_REG
:
3021 case OP_STORER4_MEMBASE_REG
:
3022 case OP_STORER8_MEMBASE_REG
:
3023 case OP_STORE_MEMBASE_REG
: {
3025 LLVMValueRef index
, addr
;
3027 gboolean sext
= FALSE
, zext
= FALSE
;
3028 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3030 if (!values
[ins
->inst_destbasereg
])
3031 LLVM_FAILURE (ctx
, "inst_destbasereg");
3033 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3035 if (ins
->inst_offset
% size
!= 0) {
3036 /* Unaligned store */
3037 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3038 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3040 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3041 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3043 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), is_volatile
);
3047 case OP_STOREI1_MEMBASE_IMM
:
3048 case OP_STOREI2_MEMBASE_IMM
:
3049 case OP_STOREI4_MEMBASE_IMM
:
3050 case OP_STOREI8_MEMBASE_IMM
:
3051 case OP_STORE_MEMBASE_IMM
: {
3053 LLVMValueRef index
, addr
;
3055 gboolean sext
= FALSE
, zext
= FALSE
;
3056 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
3058 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
3060 if (ins
->inst_offset
% size
!= 0) {
3061 /* Unaligned store */
3062 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
3063 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
3065 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3066 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
3068 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), addr
, is_volatile
);
3073 emit_load (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
3075 case OP_OUTARG_VTRETADDR
:
3082 case OP_VOIDCALL_MEMBASE
:
3083 case OP_CALL_MEMBASE
:
3084 case OP_LCALL_MEMBASE
:
3085 case OP_FCALL_MEMBASE
:
3086 case OP_VCALL_MEMBASE
:
3087 case OP_VOIDCALL_REG
:
3091 case OP_VCALL_REG
: {
3092 process_call (ctx
, bb
, &builder
, ins
);
3093 CHECK_FAILURE (ctx
);
3098 LLVMValueRef indexes
[2];
3100 LLVMValueRef got_entry_addr
;
3103 * FIXME: Can't allocate from the cfg mempool since that is freed if
3104 * the LLVM compile fails.
3106 ji
= g_new0 (MonoJumpInfo
, 1);
3107 ji
->type
= (MonoJumpInfoType
)ins
->inst_i1
;
3108 ji
->data
.target
= ins
->inst_p0
;
3110 ji
= mono_aot_patch_info_dup (ji
);
3112 ji
->next
= cfg
->patch_info
;
3113 cfg
->patch_info
= ji
;
3115 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3116 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
3118 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3119 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
3120 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->lmodule
->got_var
, indexes
, 2, "");
3122 // FIXME: This doesn't work right now, because it must be
3123 // paired with an invariant.end, and even then, its only in effect
3124 // inside its basic block
3127 LLVMValueRef args
[3];
3128 LLVMValueRef ptr
, val
;
3130 ptr
= LLVMBuildBitCast (builder
, got_entry_addr
, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3132 args
[0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer
), FALSE
);
3134 val
= LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.invariant.start"), args
, 2, "");
3138 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, dname
);
3141 case OP_NOT_REACHED
:
3142 LLVMBuildUnreachable (builder
);
3143 has_terminator
= TRUE
;
3144 g_assert (bb
->block_num
< cfg
->max_block_num
);
3145 ctx
->unreachable
[bb
->block_num
] = TRUE
;
3146 /* Might have instructions after this */
3148 MonoInst
*next
= ins
->next
;
3150 * FIXME: If later code uses the regs defined by these instructions,
3151 * compilation will fail.
3153 MONO_DELETE_INS (bb
, next
);
3157 MonoInst
*var
= ins
->inst_p0
;
3159 values
[ins
->dreg
] = addresses
[var
->dreg
];
3163 LLVMValueRef args
[1];
3165 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3166 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sin.f64"), args
, 1, dname
);
3170 LLVMValueRef args
[1];
3172 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3173 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.cos.f64"), args
, 1, dname
);
3177 LLVMValueRef args
[1];
3180 /* This no longer seems to happen */
3182 * LLVM optimizes sqrt(nan) into undefined in
3183 * lib/Analysis/ConstantFolding.cpp
3184 * Also, sqrt(NegativeInfinity) is optimized into 0.
3186 LLVM_FAILURE (ctx
, "sqrt");
3189 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sqrt.f64"), args
, 1, dname
);
3193 LLVMValueRef args
[1];
3196 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "fabs"), args
, 1, dname
);
3210 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3211 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
3213 switch (ins
->opcode
) {
3216 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
3220 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
3224 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
3228 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
3231 g_assert_not_reached ();
3234 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3237 case OP_ATOMIC_EXCHANGE_I4
: {
3238 LLVMValueRef args
[2];
3240 g_assert (ins
->inst_offset
== 0);
3242 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3244 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i32.p0i32"), args
, 2, dname
);
3247 case OP_ATOMIC_EXCHANGE_I8
: {
3248 LLVMValueRef args
[2];
3250 g_assert (ins
->inst_offset
== 0);
3252 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3253 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3254 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i64.p0i64"), args
, 2, dname
);
3257 case OP_ATOMIC_ADD_NEW_I4
: {
3258 LLVMValueRef args
[2];
3260 g_assert (ins
->inst_offset
== 0);
3262 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3264 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i32.p0i32"), args
, 2, ""), args
[1], dname
);
3267 case OP_ATOMIC_ADD_NEW_I8
: {
3268 LLVMValueRef args
[2];
3270 g_assert (ins
->inst_offset
== 0);
3272 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3273 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3274 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i64.p0i64"), args
, 2, ""), args
[1], dname
);
3277 case OP_ATOMIC_CAS_I4
:
3278 case OP_ATOMIC_CAS_I8
: {
3279 LLVMValueRef args
[3];
3281 const char *intrins
;
3283 if (ins
->opcode
== OP_ATOMIC_CAS_I4
) {
3284 t
= LLVMInt32Type ();
3285 intrins
= "llvm.atomic.cmp.swap.i32.p0i32";
3287 t
= LLVMInt64Type ();
3288 intrins
= "llvm.atomic.cmp.swap.i64.p0i64";
3291 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
3293 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
3295 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
3296 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, intrins
), args
, 3, dname
);
3299 case OP_MEMORY_BARRIER
: {
3300 LLVMValueRef args
[5];
3303 /* Not yet supported by llc on arm */
3304 LLVM_FAILURE (ctx
, "memory-barrier+arm");
3307 for (i
= 0; i
< 5; ++i
)
3308 args
[i
] = LLVMConstInt (LLVMInt1Type (), TRUE
, TRUE
);
3310 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.memory.barrier"), args
, 5, "");
3313 case OP_RELAXED_NOP
: {
3314 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3315 if (IS_LLVM_MONO_BRANCH
)
3316 emit_call (ctx
, bb
, &builder
, LLVMGetNamedFunction (ctx
->module
, "llvm.x86.sse2.pause"), NULL
, 0);
3318 /* No way to get LLVM to emit this */
3319 LLVM_FAILURE (ctx
, "relaxed_nop");
3326 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3328 // 257 == FS segment register
3329 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
3331 // 256 == GS segment register
3332 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
3336 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
3338 LLVM_FAILURE (ctx
, "opcode tls-get");
3348 case OP_IADD_OVF_UN
:
3350 case OP_ISUB_OVF_UN
:
3352 case OP_IMUL_OVF_UN
:
3353 #if SIZEOF_VOID_P == 8
3355 case OP_LADD_OVF_UN
:
3357 case OP_LSUB_OVF_UN
:
3359 case OP_LMUL_OVF_UN
:
3362 LLVMValueRef args
[2], val
, ovf
, func
;
3364 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
3365 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
3366 func
= LLVMGetNamedFunction (module
, ovf_op_to_intrins (ins
->opcode
));
3368 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
3369 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
3370 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
3371 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
3372 CHECK_FAILURE (ctx
);
3373 builder
= ctx
->builder
;
3379 * We currently model them using arrays. Promotion to local vregs is
3380 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3381 * so we always have an entry in cfg->varinfo for them.
3382 * FIXME: Is this needed ?
3385 MonoClass
*klass
= ins
->klass
;
3386 LLVMValueRef args
[5];
3390 LLVM_FAILURE (ctx
, "!klass");
3394 if (!addresses
[ins
->dreg
])
3395 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3396 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3397 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
3398 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3400 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3401 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3402 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
3406 case OP_STOREV_MEMBASE
:
3407 case OP_LOADV_MEMBASE
:
3409 MonoClass
*klass
= ins
->klass
;
3410 LLVMValueRef src
, dst
, args
[5];
3411 gboolean done
= FALSE
;
3415 LLVM_FAILURE (ctx
, "!klass");
3419 switch (ins
->opcode
) {
3420 case OP_STOREV_MEMBASE
:
3421 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
) {
3422 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3423 LLVM_FAILURE (ctx
, "storev_membase + write barriers");
3426 if (!addresses
[ins
->sreg1
]) {
3428 g_assert (values
[ins
->sreg1
]);
3429 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));
3430 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
3433 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3434 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3437 case OP_LOADV_MEMBASE
:
3438 if (!addresses
[ins
->dreg
])
3439 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3440 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3441 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3444 if (!addresses
[ins
->sreg1
])
3445 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
3446 if (!addresses
[ins
->dreg
])
3447 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3448 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3449 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3452 g_assert_not_reached ();
3454 CHECK_FAILURE (ctx
);
3461 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3462 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3464 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3465 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3466 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memcpy_func_name
), args
, memcpy_param_count
, "");
3469 case OP_LLVM_OUTARG_VT
:
3470 if (!addresses
[ins
->sreg1
]) {
3471 addresses
[ins
->sreg1
] = build_alloca (ctx
, &ins
->klass
->byval_arg
);
3472 g_assert (values
[ins
->sreg1
]);
3473 LLVMBuildStore (builder
, values
[ins
->sreg1
], addresses
[ins
->sreg1
]);
3475 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
3481 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3483 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
3486 case OP_LOADX_MEMBASE
: {
3487 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
3490 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3491 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
3494 case OP_STOREX_MEMBASE
: {
3495 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
3498 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3499 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
3506 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
3510 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
3516 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
3520 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
3524 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
3528 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
3531 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
3534 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
3537 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
3541 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
3554 switch (ins
->opcode
) {
3559 t
= LLVMVectorType (LLVMInt32Type (), 4);
3560 rt
= LLVMVectorType (LLVMFloatType (), 4);
3566 t
= LLVMVectorType (LLVMInt64Type (), 2);
3567 rt
= LLVMVectorType (LLVMDoubleType (), 2);
3570 t
= LLVMInt32Type ();
3571 rt
= LLVMInt32Type ();
3572 g_assert_not_reached ();
3575 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3576 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
3577 switch (ins
->opcode
) {
3580 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
3584 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
3588 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
3592 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
3595 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
3619 case OP_PADDB_SAT_UN
:
3620 case OP_PADDW_SAT_UN
:
3621 case OP_PSUBB_SAT_UN
:
3622 case OP_PSUBW_SAT_UN
:
3635 case OP_PMULW_HIGH_UN
: {
3636 LLVMValueRef args
[2];
3641 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3649 case OP_EXTRACTX_U2
:
3651 case OP_EXTRACT_U1
: {
3653 gboolean zext
= FALSE
;
3655 t
= simd_op_to_llvm_type (ins
->opcode
);
3657 switch (ins
->opcode
) {
3665 case OP_EXTRACTX_U2
:
3670 t
= LLVMInt32Type ();
3671 g_assert_not_reached ();
3674 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3675 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
3677 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
3686 case OP_EXPAND_R8
: {
3687 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3688 LLVMValueRef mask
[16], v
;
3690 for (i
= 0; i
< 16; ++i
)
3691 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3693 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
3695 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3696 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
3701 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3704 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3707 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3710 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3713 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3716 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
3727 case OP_EXTRACT_MASK
:
3734 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
3736 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
3740 case OP_ICONV_TO_R8_RAW
:
3741 /* Same as OP_ICONV_TO_R8 */
3742 values
[ins
->dreg
] = convert (ctx
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType ());
3747 LLVMValueRef args
[3];
3751 args
[2] = LLVMConstInt (LLVMInt8Type (), ins
->inst_c0
, FALSE
);
3753 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
3758 /* This is only used for implementing shifts by non-immediate */
3759 values
[ins
->dreg
] = lhs
;
3770 LLVMValueRef args
[3];
3773 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
3775 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3786 case OP_PSHLQ_REG
: {
3787 LLVMValueRef args
[3];
3790 args
[1] = values
[ins
->sreg2
];
3792 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3799 case OP_PSHUFLEW_LOW
:
3800 case OP_PSHUFLEW_HIGH
: {
3802 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[4];
3803 int i
, mask_size
= 0;
3804 int imask
= ins
->inst_c0
;
3806 /* Convert the x86 shuffle mask to LLVM's */
3807 switch (ins
->opcode
) {
3810 mask
[0] = ((imask
>> 0) & 3);
3811 mask
[1] = ((imask
>> 2) & 3);
3812 mask
[2] = ((imask
>> 4) & 3) + 4;
3813 mask
[3] = ((imask
>> 6) & 3) + 4;
3814 v1
= values
[ins
->sreg1
];
3815 v2
= values
[ins
->sreg2
];
3819 mask
[0] = ((imask
>> 0) & 1);
3820 mask
[1] = ((imask
>> 1) & 1) + 2;
3821 v1
= values
[ins
->sreg1
];
3822 v2
= values
[ins
->sreg2
];
3824 case OP_PSHUFLEW_LOW
:
3826 mask
[0] = ((imask
>> 0) & 3);
3827 mask
[1] = ((imask
>> 2) & 3);
3828 mask
[2] = ((imask
>> 4) & 3);
3829 mask
[3] = ((imask
>> 6) & 3);
3834 v1
= values
[ins
->sreg1
];
3835 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3837 case OP_PSHUFLEW_HIGH
:
3843 mask
[4] = 4 + ((imask
>> 0) & 3);
3844 mask
[5] = 4 + ((imask
>> 2) & 3);
3845 mask
[6] = 4 + ((imask
>> 4) & 3);
3846 mask
[7] = 4 + ((imask
>> 6) & 3);
3847 v1
= values
[ins
->sreg1
];
3848 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3852 mask
[0] = ((imask
>> 0) & 3);
3853 mask
[1] = ((imask
>> 2) & 3);
3854 mask
[2] = ((imask
>> 4) & 3);
3855 mask
[3] = ((imask
>> 6) & 3);
3856 v1
= values
[ins
->sreg1
];
3857 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
3860 g_assert_not_reached ();
3862 for (i
= 0; i
< mask_size
; ++i
)
3863 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3865 values
[ins
->dreg
] =
3866 LLVMBuildShuffleVector (builder
, v1
, v2
,
3867 LLVMConstVector (mask_values
, mask_size
), dname
);
3871 case OP_UNPACK_LOWB
:
3872 case OP_UNPACK_LOWW
:
3873 case OP_UNPACK_LOWD
:
3874 case OP_UNPACK_LOWQ
:
3875 case OP_UNPACK_LOWPS
:
3876 case OP_UNPACK_LOWPD
:
3877 case OP_UNPACK_HIGHB
:
3878 case OP_UNPACK_HIGHW
:
3879 case OP_UNPACK_HIGHD
:
3880 case OP_UNPACK_HIGHQ
:
3881 case OP_UNPACK_HIGHPS
:
3882 case OP_UNPACK_HIGHPD
: {
3884 LLVMValueRef mask_values
[16];
3885 int i
, mask_size
= 0;
3886 gboolean low
= FALSE
;
3888 switch (ins
->opcode
) {
3889 case OP_UNPACK_LOWB
:
3893 case OP_UNPACK_LOWW
:
3897 case OP_UNPACK_LOWD
:
3898 case OP_UNPACK_LOWPS
:
3902 case OP_UNPACK_LOWQ
:
3903 case OP_UNPACK_LOWPD
:
3907 case OP_UNPACK_HIGHB
:
3910 case OP_UNPACK_HIGHW
:
3913 case OP_UNPACK_HIGHD
:
3914 case OP_UNPACK_HIGHPS
:
3917 case OP_UNPACK_HIGHQ
:
3918 case OP_UNPACK_HIGHPD
:
3922 g_assert_not_reached ();
3926 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3928 mask
[(i
* 2) + 1] = mask_size
+ i
;
3931 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
3932 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
3933 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
3937 for (i
= 0; i
< mask_size
; ++i
)
3938 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
3940 values
[ins
->dreg
] =
3941 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
3942 LLVMConstVector (mask_values
, mask_size
), dname
);
3947 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3948 LLVMValueRef v
, val
;
3950 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3951 val
= LLVMConstNull (t
);
3952 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3953 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
3955 values
[ins
->dreg
] = val
;
3959 case OP_DUPPS_HIGH
: {
3960 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
3961 LLVMValueRef v1
, v2
, val
;
3964 if (ins
->opcode
== OP_DUPPS_LOW
) {
3965 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3966 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3968 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3969 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3971 val
= LLVMConstNull (t
);
3972 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
3973 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
3974 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
3975 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
3977 values
[ins
->dreg
] = val
;
3987 * EXCEPTION HANDLING
3989 case OP_IMPLICIT_EXCEPTION
:
3990 /* This marks a place where an implicit exception can happen */
3991 if (bb
->region
!= -1)
3992 LLVM_FAILURE (ctx
, "implicit-exception");
3996 MonoMethodSignature
*throw_sig
;
3997 LLVMValueRef callee
, arg
;
3998 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
3999 const char *icall_name
;
4001 callee
= rethrow
? ctx
->lmodule
->rethrow
: ctx
->lmodule
->throw;
4002 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4005 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
4006 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
4007 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
4008 if (cfg
->compile_aot
) {
4009 callee
= get_plt_entry (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
4011 callee
= LLVMAddFunction (module
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
));
4015 * LLVM doesn't push the exception argument, so we need a different
4018 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4020 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
4024 mono_memory_barrier ();
4026 ctx
->lmodule
->rethrow
= callee
;
4028 ctx
->lmodule
->throw = callee
;
4030 arg
= convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
4031 emit_call (ctx
, bb
, &builder
, callee
, &arg
, 1);
4034 case OP_CALL_HANDLER
: {
4036 * We don't 'call' handlers, but instead simply branch to them.
4037 * The code generated by ENDFINALLY will branch back to us.
4039 LLVMBasicBlockRef noex_bb
;
4041 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
4043 bb_list
= info
->call_handler_return_bbs
;
4046 * Set the indicator variable for the finally clause.
4048 lhs
= info
->finally_ind
;
4050 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
4052 /* Branch to the finally clause */
4053 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
4055 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
4056 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
4058 builder
= ctx
->builder
= create_builder (ctx
);
4059 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
4061 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
4064 case OP_START_HANDLER
: {
4067 case OP_ENDFINALLY
: {
4068 LLVMBasicBlockRef resume_bb
;
4069 MonoBasicBlock
*handler_bb
;
4070 LLVMValueRef val
, switch_ins
, callee
;
4074 handler_bb
= g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
4075 g_assert (handler_bb
);
4076 info
= &bblocks
[handler_bb
->block_num
];
4077 lhs
= info
->finally_ind
;
4080 bb_list
= info
->call_handler_return_bbs
;
4082 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
4084 /* Load the finally variable */
4085 val
= LLVMBuildLoad (builder
, lhs
, "");
4087 /* Reset the variable */
4088 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
4090 /* Branch to either resume_bb, or to the bblocks in bb_list */
4091 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
4093 * The other targets are added at the end to handle OP_CALL_HANDLER
4094 * opcodes processed later.
4096 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
4098 builder
= ctx
->builder
= create_builder (ctx
);
4099 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
4101 if (ctx
->cfg
->compile_aot
) {
4102 callee
= get_plt_entry (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
4104 callee
= LLVMGetNamedFunction (module
, "llvm_resume_unwind_trampoline");
4106 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
4108 LLVMBuildUnreachable (builder
);
4109 has_terminator
= TRUE
;
4115 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
4116 LLVM_FAILURE (ctx
, reason
);
4121 /* Convert the value to the type required by phi nodes */
4122 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
4123 if (!values
[ins
->dreg
])
4125 values
[ins
->dreg
] = addresses
[ins
->dreg
];
4127 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
4130 /* Add stores for volatile variables */
4131 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
4132 emit_volatile_store (ctx
, ins
->dreg
);
4135 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4136 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
4138 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
)
4139 LLVMBuildRetVoid (builder
);
4141 if (bb
== cfg
->bb_entry
)
4142 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
4151 * mono_llvm_check_method_supported:
4153 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4154 * compiling a method twice.
4157 mono_llvm_check_method_supported (MonoCompile
*cfg
)
4160 MonoMethodHeader *header = cfg->header;
4161 MonoExceptionClause *clause;
4165 if (cfg
->generic_sharing_context
&& !IS_LLVM_MONO_BRANCH
) {
4166 /* No way to obtain location info for this/rgctx */
4167 cfg
->exception_message
= g_strdup ("gshared");
4168 cfg
->disable_llvm
= TRUE
;
4171 if (cfg
->method
->save_lmf
) {
4172 cfg
->exception_message
= g_strdup ("lmf");
4173 cfg
->disable_llvm
= TRUE
;
4177 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4178 clause
= &header
->clauses
[i
];
4180 if (i
> 0 && clause
->try_offset
<= header
->clauses
[i
- 1].handler_offset
+ header
->clauses
[i
- 1].handler_len
) {
4182 * FIXME: Some tests still fail with nested clauses.
4184 cfg
->exception_message
= g_strdup ("nested clauses");
4185 cfg
->disable_llvm
= TRUE
;
4191 if (cfg
->method
->dynamic
) {
4192 cfg
->exception_message
= g_strdup ("dynamic.");
4193 cfg
->disable_llvm
= TRUE
;
4198 * mono_llvm_emit_method:
4200 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4203 mono_llvm_emit_method (MonoCompile
*cfg
)
4206 MonoMethodSignature
*sig
;
4208 LLVMTypeRef method_type
;
4209 LLVMValueRef method
= NULL
;
4211 LLVMValueRef
*values
;
4212 int i
, max_block_num
, bb_index
;
4213 gboolean last
= FALSE
;
4214 GPtrArray
*phi_values
;
4215 LLVMCallInfo
*linfo
;
4217 LLVMModuleRef module
;
4219 GPtrArray
*bblock_list
;
4220 MonoMethodHeader
*header
;
4221 MonoExceptionClause
*clause
;
4225 /* The code below might acquire the loader lock, so use it for global locking */
4226 mono_loader_lock ();
4228 /* Used to communicate with the callbacks */
4229 TlsSetValue (current_cfg_tls_id
, cfg
);
4231 ctx
= g_new0 (EmitContext
, 1);
4233 ctx
->mempool
= cfg
->mempool
;
4236 * This maps vregs to the LLVM instruction defining them
4238 values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4240 * This maps vregs for volatile variables to the LLVM instruction defining their
4243 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
4244 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
4245 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
4246 phi_values
= g_ptr_array_new ();
4248 * This signals whenever the vreg was defined by a phi node with no input vars
4249 * (i.e. all its input bblocks end with NOT_REACHABLE).
4251 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
4252 /* Whenever the bblock is unreachable */
4253 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
4255 bblock_list
= g_ptr_array_new ();
4257 ctx
->values
= values
;
4258 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
4260 if (cfg
->compile_aot
) {
4261 ctx
->lmodule
= &aot_module
;
4262 method_name
= mono_aot_get_method_name (cfg
);
4263 cfg
->llvm_method_name
= g_strdup (method_name
);
4266 ctx
->lmodule
= &jit_module
;
4267 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
4270 module
= ctx
->module
= ctx
->lmodule
->module
;
4274 static int count
= 0;
4277 if (getenv ("LLVM_COUNT")) {
4278 if (count
== atoi (getenv ("LLVM_COUNT"))) {
4279 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
4283 if (count
> atoi (getenv ("LLVM_COUNT")))
4284 LLVM_FAILURE (ctx
, "");
4289 sig
= mono_method_signature (cfg
->method
);
4292 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4294 CHECK_FAILURE (ctx
);
4296 if (cfg
->rgctx_var
) {
4297 if (IS_LLVM_MONO_BRANCH
)
4298 linfo
->rgctx_arg
= TRUE
;
4300 LLVM_FAILURE (ctx
, "rgctx arg");
4302 method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
, &sinfo
);
4303 CHECK_FAILURE (ctx
);
4306 * This maps parameter indexes in the original signature to the indexes in
4307 * the LLVM signature.
4309 ctx
->pindexes
= sinfo
.pindexes
;
4311 method
= LLVMAddFunction (module
, method_name
, method_type
);
4312 ctx
->lmethod
= method
;
4314 #ifdef LLVM_MONO_BRANCH
4315 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
4317 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4319 LLVMAddFunctionAttr (method
, LLVMUWTableAttribute
);
4321 if (cfg
->compile_aot
) {
4322 LLVMSetLinkage (method
, LLVMInternalLinkage
);
4323 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
4325 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
4328 if (cfg
->method
->save_lmf
)
4329 LLVM_FAILURE (ctx
, "lmf");
4331 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
)
4332 LLVM_FAILURE (ctx
, "pinvoke signature");
4334 header
= cfg
->header
;
4335 for (i
= 0; i
< header
->num_clauses
; ++i
) {
4336 clause
= &header
->clauses
[i
];
4337 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
)
4338 LLVM_FAILURE (ctx
, "non-finally/catch clause.");
4341 if (linfo
->rgctx_arg
) {
4342 ctx
->rgctx_arg
= LLVMGetParam (method
, sinfo
.rgctx_arg_pindex
);
4344 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4345 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4346 * CC_X86_64_Mono in X86CallingConv.td.
4348 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
4349 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
4351 if (cfg
->vret_addr
) {
4352 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, sinfo
.vret_arg_pindex
);
4353 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
4356 values
[cfg
->args
[0]->dreg
] = LLVMGetParam (method
, sinfo
.this_arg_pindex
);
4357 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
4360 names
= g_new (char *, sig
->param_count
);
4361 mono_method_get_param_names (cfg
->method
, (const char **) names
);
4363 for (i
= 0; i
< sig
->param_count
; ++i
) {
4366 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, sinfo
.pindexes
[i
]);
4367 if (names
[i
] && names
[i
][0] != '\0')
4368 name
= g_strdup_printf ("arg_%s", names
[i
]);
4370 name
= g_strdup_printf ("arg_%d", i
);
4371 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
4373 if (linfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
)
4374 LLVMAddAttribute (LLVMGetParam (method
, sinfo
.pindexes
[i
]), LLVMByValAttribute
);
4379 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
4380 max_block_num
= MAX (max_block_num
, bb
->block_num
);
4381 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
4383 /* Add branches between non-consecutive bblocks */
4384 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4385 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
4386 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
4388 MonoInst
*inst
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
4389 inst
->opcode
= OP_BR
;
4390 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
4391 mono_bblock_add_inst (bb
, inst
);
4396 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4397 * was later optimized away, so clear these flags, and add them back for the still
4398 * present OP_LDADDR instructions.
4400 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
4403 ins
= get_vreg_to_inst (cfg
, i
);
4404 if (ins
&& ins
!= cfg
->rgctx_var
)
4405 ins
->flags
&= ~MONO_INST_INDIRECT
;
4409 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4411 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4413 LLVMBuilderRef builder
;
4415 char dname_buf
[128];
4417 builder
= create_builder (ctx
);
4419 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4420 switch (ins
->opcode
) {
4425 LLVMTypeRef phi_type
= llvm_type_to_stack_type (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
4427 CHECK_FAILURE (ctx
);
4429 if (ins
->opcode
== OP_VPHI
) {
4430 /* Treat valuetype PHI nodes as operating on the address itself */
4431 g_assert (ins
->klass
);
4432 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
4436 * Have to precreate these, as they can be referenced by
4437 * earlier instructions.
4439 sprintf (dname_buf
, "t%d", ins
->dreg
);
4441 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
4443 if (ins
->opcode
== OP_VPHI
)
4444 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
4446 g_ptr_array_add (phi_values
, values
[ins
->dreg
]);
4449 * Set the expected type of the incoming arguments since these have
4450 * to have the same type.
4452 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4453 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4456 ctx
->vreg_types
[sreg1
] = phi_type
;
4461 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
4470 * Create an ordering for bblocks, use the depth first order first, then
4471 * put the exception handling bblocks last.
4473 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
4474 bb
= cfg
->bblocks
[bb_index
];
4475 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
4476 g_ptr_array_add (bblock_list
, bb
);
4477 bblocks
[bb
->block_num
].added
= TRUE
;
4481 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4482 if (!bblocks
[bb
->block_num
].added
)
4483 g_ptr_array_add (bblock_list
, bb
);
4487 * Second pass: generate code.
4489 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
4490 bb
= g_ptr_array_index (bblock_list
, bb_index
);
4492 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
4495 process_bb (ctx
, bb
);
4496 CHECK_FAILURE (ctx
);
4499 /* Add incoming phi values */
4500 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4501 GSList
*l
, *ins_list
;
4503 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
4505 for (l
= ins_list
; l
; l
= l
->next
) {
4506 PhiNode
*node
= l
->data
;
4507 MonoInst
*phi
= node
->phi
;
4508 int sreg1
= node
->sreg
;
4509 LLVMBasicBlockRef in_bb
;
4514 in_bb
= get_end_bb (ctx
, node
->in_bb
);
4516 if (ctx
->unreachable
[node
->in_bb
->block_num
])
4519 g_assert (values
[sreg1
]);
4521 if (phi
->opcode
== OP_VPHI
) {
4522 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4523 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
4525 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
4526 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
4531 /* Create the SWITCH statements for ENDFINALLY instructions */
4532 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
4533 BBInfo
*info
= &bblocks
[bb
->block_num
];
4535 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
4536 LLVMValueRef switch_ins
= l
->data
;
4537 GSList
*bb_list
= info
->call_handler_return_bbs
;
4539 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
4540 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), g_slist_nth (bb_list
, i
)->data
);
4544 if (cfg
->verbose_level
> 1)
4545 mono_llvm_dump_value (method
);
4547 mark_as_used (module
, method
);
4549 if (cfg
->compile_aot
) {
4550 /* Don't generate native code, keep the LLVM IR */
4551 if (cfg
->compile_aot
&& cfg
->verbose_level
)
4552 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), method_name
);
4554 //LLVMVerifyFunction(method, 0);
4556 mono_llvm_optimize_method (method
);
4558 if (cfg
->verbose_level
> 1)
4559 mono_llvm_dump_value (method
);
4561 cfg
->native_code
= LLVMGetPointerToGlobal (ee
, method
);
4563 /* Set by emit_cb */
4564 g_assert (cfg
->code_len
);
4566 /* FIXME: Free the LLVM IL for the function */
4574 /* Need to add unused phi nodes as they can be referenced by other values */
4575 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (method
, "PHI_BB");
4576 LLVMBuilderRef builder
;
4578 builder
= create_builder (ctx
);
4579 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
4581 for (i
= 0; i
< phi_values
->len
; ++i
) {
4582 LLVMValueRef v
= g_ptr_array_index (phi_values
, i
);
4583 if (LLVMGetInstructionParent (v
) == NULL
)
4584 LLVMInsertIntoBuilder (builder
, v
);
4587 LLVMDeleteFunction (method
);
4592 g_free (ctx
->addresses
);
4593 g_free (ctx
->vreg_types
);
4594 g_free (ctx
->vreg_cli_types
);
4595 g_free (ctx
->pindexes
);
4596 g_free (ctx
->is_dead
);
4597 g_free (ctx
->unreachable
);
4598 g_ptr_array_free (phi_values
, TRUE
);
4599 g_free (ctx
->bblocks
);
4600 g_hash_table_destroy (ctx
->region_to_handler
);
4601 g_free (method_name
);
4602 g_ptr_array_free (bblock_list
, TRUE
);
4604 for (l
= ctx
->builders
; l
; l
= l
->next
) {
4605 LLVMBuilderRef builder
= l
->data
;
4606 LLVMDisposeBuilder (builder
);
4611 TlsSetValue (current_cfg_tls_id
, NULL
);
4613 mono_loader_unlock ();
4617 * mono_llvm_emit_call:
4619 * Same as mono_arch_emit_call () for LLVM.
4622 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
4625 MonoMethodSignature
*sig
;
4626 int i
, n
, stack_size
;
4631 sig
= call
->signature
;
4632 n
= sig
->param_count
+ sig
->hasthis
;
4634 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4636 if (cfg
->disable_llvm
)
4639 if (sig
->call_convention
== MONO_CALL_VARARG
) {
4640 cfg
->exception_message
= g_strdup ("varargs");
4641 cfg
->disable_llvm
= TRUE
;
4644 for (i
= 0; i
< n
; ++i
) {
4647 ainfo
= call
->cinfo
->args
+ i
;
4649 in
= call
->args
[i
];
4651 /* Simply remember the arguments */
4652 switch (ainfo
->storage
) {
4654 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
4655 ins
->dreg
= mono_alloc_ireg (cfg
);
4656 ins
->sreg1
= in
->dreg
;
4658 case LLVMArgInFPReg
:
4659 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
4660 ins
->dreg
= mono_alloc_freg (cfg
);
4661 ins
->sreg1
= in
->dreg
;
4663 case LLVMArgVtypeByVal
:
4664 case LLVMArgVtypeInReg
:
4665 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
4666 ins
->dreg
= mono_alloc_ireg (cfg
);
4667 ins
->sreg1
= in
->dreg
;
4668 ins
->klass
= mono_class_from_mono_type (sig
->params
[i
- sig
->hasthis
]);
4671 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
4672 cfg
->exception_message
= g_strdup ("ainfo->storage");
4673 cfg
->disable_llvm
= TRUE
;
4677 if (!cfg
->disable_llvm
) {
4678 MONO_ADD_INS (cfg
->cbb
, ins
);
4679 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
4684 static unsigned char*
4685 alloc_cb (LLVMValueRef function
, int size
)
4689 cfg
= TlsGetValue (current_cfg_tls_id
);
4693 return mono_domain_code_reserve (cfg
->domain
, size
);
4695 return mono_domain_code_reserve (mono_domain_get (), size
);
4700 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
4704 cfg
= TlsGetValue (current_cfg_tls_id
);
4706 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
4710 exception_cb (void *data
)
4713 MonoJitExceptionInfo
*ei
;
4714 guint32 ei_len
, i
, j
, nested_len
, nindex
;
4715 gpointer
*type_info
;
4716 int this_reg
, this_offset
;
4718 cfg
= TlsGetValue (current_cfg_tls_id
);
4722 * data points to a DWARF FDE structure, convert it to our unwind format and
4724 * An alternative would be to save it directly, and modify our unwinder to work
4727 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
);
4729 /* Count nested clauses */
4731 for (i
= 0; i
< ei_len
; ++i
) {
4732 for (j
= 0; j
< ei_len
; ++j
) {
4733 gint32 cindex1
= *(gint32
*)type_info
[i
];
4734 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4735 gint32 cindex2
= *(gint32
*)type_info
[j
];
4736 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4738 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4744 cfg
->llvm_ex_info
= mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
4745 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
4746 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
4747 /* Fill the rest of the information from the type info */
4748 for (i
= 0; i
< ei_len
; ++i
) {
4749 gint32 clause_index
= *(gint32
*)type_info
[i
];
4750 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
4752 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
4753 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
4757 * For nested clauses, the LLVM produced exception info associates the try interval with
4758 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4760 /* FIXME: These should be order with the normal clauses */
4762 for (i
= 0; i
< ei_len
; ++i
) {
4763 for (j
= 0; j
< ei_len
; ++j
) {
4764 gint32 cindex1
= *(gint32
*)type_info
[i
];
4765 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
4766 gint32 cindex2
= *(gint32
*)type_info
[j
];
4767 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
4769 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
4771 * The try interval comes from the nested clause, everything else from the
4774 memcpy (&cfg
->llvm_ex_info
[nindex
], &cfg
->llvm_ex_info
[j
], sizeof (MonoJitExceptionInfo
));
4775 cfg
->llvm_ex_info
[nindex
].try_start
= cfg
->llvm_ex_info
[i
].try_start
;
4776 cfg
->llvm_ex_info
[nindex
].try_end
= cfg
->llvm_ex_info
[i
].try_end
;
4781 g_assert (nindex
== ei_len
+ nested_len
);
4782 cfg
->llvm_this_reg
= this_reg
;
4783 cfg
->llvm_this_offset
= this_offset
;
4785 /* type_info [i] is cfg mempool allocated, no need to free it */
4792 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
4794 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
4798 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
4800 LLVMTypeRef param_types
[4];
4802 param_types
[0] = param_type1
;
4803 param_types
[1] = param_type2
;
4805 AddFunc (module
, name
, ret_type
, param_types
, 2);
4809 add_intrinsics (LLVMModuleRef module
)
4811 /* Emit declarations of instrinsics */
4813 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4814 * type doesn't seem to do any locking.
4817 LLVMTypeRef memset_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4819 memset_param_count
= 5;
4820 memset_func_name
= "llvm.memset.p0i8.i32";
4822 LLVMAddFunction (module
, memset_func_name
, LLVMFunctionType (LLVMVoidType (), memset_params
, memset_param_count
, FALSE
));
4826 LLVMTypeRef memcpy_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4828 memcpy_param_count
= 5;
4829 memcpy_func_name
= "llvm.memcpy.p0i8.p0i8.i32";
4831 LLVMAddFunction (module
, memcpy_func_name
, LLVMFunctionType (LLVMVoidType (), memcpy_params
, memcpy_param_count
, FALSE
));
4835 LLVMTypeRef params
[] = { LLVMDoubleType () };
4837 LLVMAddFunction (module
, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4838 LLVMAddFunction (module
, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4839 LLVMAddFunction (module
, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4841 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4842 LLVMAddFunction (module
, "fabs", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
4846 LLVMTypeRef membar_params
[] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
4848 LLVMAddFunction (module
, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
4849 LLVMAddFunction (module
, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
4850 LLVMAddFunction (module
, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
4851 LLVMAddFunction (module
, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
4852 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE
));
4853 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE
));
4854 LLVMAddFunction (module
, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params
, 5, FALSE
));
4858 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
4859 LLVMTypeRef ovf_params_i32
[] = { LLVMInt32Type (), LLVMInt32Type () };
4861 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4862 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4863 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4864 LLVMAddFunction (module
, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4865 LLVMAddFunction (module
, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4866 LLVMAddFunction (module
, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
4870 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
4871 LLVMTypeRef ovf_params_i64
[] = { LLVMInt64Type (), LLVMInt64Type () };
4873 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4874 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4875 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4876 LLVMAddFunction (module
, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4877 LLVMAddFunction (module
, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4878 LLVMAddFunction (module
, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
4882 LLVMTypeRef struct_ptr
= LLVMPointerType (LLVMStructType (NULL
, 0, FALSE
), 0);
4883 LLVMTypeRef invariant_start_params
[] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4884 LLVMTypeRef invariant_end_params
[] = { struct_ptr
, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4886 LLVMAddFunction (module
, "llvm.invariant.start", LLVMFunctionType (struct_ptr
, invariant_start_params
, 2, FALSE
));
4888 LLVMAddFunction (module
, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params
, 3, FALSE
));
4893 LLVMTypeRef arg_types
[2];
4894 LLVMTypeRef ret_type
;
4896 arg_types
[0] = LLVMPointerType (LLVMInt8Type (), 0);
4897 arg_types
[1] = LLVMPointerType (LLVMInt8Type (), 0);
4898 eh_selector_name
= "llvm.eh.selector";
4899 ret_type
= LLVMInt32Type ();
4901 LLVMAddFunction (module
, eh_selector_name
, LLVMFunctionType (ret_type
, arg_types
, 2, TRUE
));
4903 LLVMAddFunction (module
, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL
, 0, FALSE
));
4905 LLVMAddFunction (module
, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4907 LLVMAddFunction (module
, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4910 /* SSE intrinsics */
4912 LLVMTypeRef ret_type
, arg_types
[2];
4915 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
4916 arg_types
[0] = ret_type
;
4917 arg_types
[1] = ret_type
;
4918 AddFunc (module
, "llvm.x86.sse41.pminud", ret_type
, arg_types
, 2);
4919 AddFunc (module
, "llvm.x86.sse41.pmaxud", ret_type
, arg_types
, 2);
4920 AddFunc (module
, "llvm.x86.sse2.pcmpeq.d", ret_type
, arg_types
, 2);
4922 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4923 arg_types
[0] = ret_type
;
4924 arg_types
[1] = ret_type
;
4925 AddFunc (module
, "llvm.x86.sse41.pminuw", ret_type
, arg_types
, 2);
4926 AddFunc (module
, "llvm.x86.sse2.pmins.w", ret_type
, arg_types
, 2);
4927 AddFunc (module
, "llvm.x86.sse41.pmaxuw", ret_type
, arg_types
, 2);
4928 AddFunc (module
, "llvm.x86.sse2.pcmpeq.w", ret_type
, arg_types
, 2);
4929 AddFunc (module
, "llvm.x86.sse2.padds.w", ret_type
, arg_types
, 2);
4930 AddFunc (module
, "llvm.x86.sse2.psubs.w", ret_type
, arg_types
, 2);
4931 AddFunc (module
, "llvm.x86.sse2.paddus.w", ret_type
, arg_types
, 2);
4932 AddFunc (module
, "llvm.x86.sse2.psubus.w", ret_type
, arg_types
, 2);
4933 AddFunc (module
, "llvm.x86.sse2.pavg.w", ret_type
, arg_types
, 2);
4934 AddFunc (module
, "llvm.x86.sse2.pmulh.w", ret_type
, arg_types
, 2);
4935 AddFunc (module
, "llvm.x86.sse2.pmulhu.w", ret_type
, arg_types
, 2);
4937 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4938 arg_types
[0] = ret_type
;
4939 arg_types
[1] = ret_type
;
4940 AddFunc (module
, "llvm.x86.sse2.pminu.b", ret_type
, arg_types
, 2);
4941 AddFunc (module
, "llvm.x86.sse2.pmaxu.b", ret_type
, arg_types
, 2);
4942 AddFunc (module
, "llvm.x86.sse2.pcmpeq.b", ret_type
, arg_types
, 2);
4943 AddFunc (module
, "llvm.x86.sse2.pcmpgt.b", ret_type
, arg_types
, 2);
4944 AddFunc (module
, "llvm.x86.sse2.padds.b", ret_type
, arg_types
, 2);
4945 AddFunc (module
, "llvm.x86.sse2.psubs.b", ret_type
, arg_types
, 2);
4946 AddFunc (module
, "llvm.x86.sse2.paddus.b", ret_type
, arg_types
, 2);
4947 AddFunc (module
, "llvm.x86.sse2.psubus.b", ret_type
, arg_types
, 2);
4948 AddFunc (module
, "llvm.x86.sse2.pavg.b", ret_type
, arg_types
, 2);
4950 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
4951 arg_types
[0] = ret_type
;
4952 arg_types
[1] = ret_type
;
4953 AddFunc (module
, "llvm.x86.sse41.pcmpeqq", ret_type
, arg_types
, 2);
4955 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4956 arg_types
[0] = ret_type
;
4957 arg_types
[1] = ret_type
;
4958 AddFunc (module
, "llvm.x86.sse2.min.pd", ret_type
, arg_types
, 2);
4959 AddFunc (module
, "llvm.x86.sse2.max.pd", ret_type
, arg_types
, 2);
4960 AddFunc (module
, "llvm.x86.sse3.hadd.pd", ret_type
, arg_types
, 2);
4961 AddFunc (module
, "llvm.x86.sse3.hsub.pd", ret_type
, arg_types
, 2);
4962 AddFunc (module
, "llvm.x86.sse3.addsub.pd", ret_type
, arg_types
, 2);
4964 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4965 arg_types
[0] = ret_type
;
4966 arg_types
[1] = ret_type
;
4967 AddFunc (module
, "llvm.x86.sse.min.ps", ret_type
, arg_types
, 2);
4968 AddFunc (module
, "llvm.x86.sse.max.ps", ret_type
, arg_types
, 2);
4969 AddFunc (module
, "llvm.x86.sse3.hadd.ps", ret_type
, arg_types
, 2);
4970 AddFunc (module
, "llvm.x86.sse3.hsub.ps", ret_type
, arg_types
, 2);
4971 AddFunc (module
, "llvm.x86.sse3.addsub.ps", ret_type
, arg_types
, 2);
4974 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
4975 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
4976 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
4977 AddFunc (module
, "llvm.x86.sse2.packsswb.128", ret_type
, arg_types
, 2);
4978 AddFunc (module
, "llvm.x86.sse2.packuswb.128", ret_type
, arg_types
, 2);
4979 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
4980 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
4981 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
4982 AddFunc (module
, "llvm.x86.sse2.packssdw.128", ret_type
, arg_types
, 2);
4983 AddFunc (module
, "llvm.x86.sse41.packusdw", ret_type
, arg_types
, 2);
4986 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4987 arg_types
[0] = ret_type
;
4988 arg_types
[1] = ret_type
;
4989 arg_types
[2] = LLVMInt8Type ();
4990 AddFunc (module
, "llvm.x86.sse2.cmp.pd", ret_type
, arg_types
, 3);
4991 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
4992 arg_types
[0] = ret_type
;
4993 arg_types
[1] = ret_type
;
4994 arg_types
[2] = LLVMInt8Type ();
4995 AddFunc (module
, "llvm.x86.sse.cmp.ps", ret_type
, arg_types
, 3);
4997 /* Conversion ops */
4998 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
4999 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
5000 AddFunc (module
, "llvm.x86.sse2.cvtdq2pd", ret_type
, arg_types
, 1);
5001 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5002 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
5003 AddFunc (module
, "llvm.x86.sse2.cvtdq2ps", ret_type
, arg_types
, 1);
5004 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5005 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5006 AddFunc (module
, "llvm.x86.sse2.cvtpd2dq", ret_type
, arg_types
, 1);
5007 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5008 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5009 AddFunc (module
, "llvm.x86.sse2.cvtps2dq", ret_type
, arg_types
, 1);
5010 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5011 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5012 AddFunc (module
, "llvm.x86.sse2.cvtpd2ps", ret_type
, arg_types
, 1);
5013 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
5014 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5015 AddFunc (module
, "llvm.x86.sse2.cvtps2pd", ret_type
, arg_types
, 1);
5017 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5018 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
5019 AddFunc (module
, "llvm.x86.sse2.cvttpd2dq", ret_type
, arg_types
, 1);
5020 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5021 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
5022 AddFunc (module
, "llvm.x86.sse2.cvttps2dq", ret_type
, arg_types
, 1);
5025 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
5026 arg_types
[0] = ret_type
;
5027 AddFunc (module
, "llvm.x86.sse2.sqrt.pd", ret_type
, arg_types
, 1);
5028 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5029 arg_types
[0] = ret_type
;
5030 AddFunc (module
, "llvm.x86.sse.sqrt.ps", ret_type
, arg_types
, 1);
5031 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5032 arg_types
[0] = ret_type
;
5033 AddFunc (module
, "llvm.x86.sse.rsqrt.ps", ret_type
, arg_types
, 1);
5034 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
5035 arg_types
[0] = ret_type
;
5036 AddFunc (module
, "llvm.x86.sse.rcp.ps", ret_type
, arg_types
, 1);
5039 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
5040 arg_types
[0] = ret_type
;
5041 arg_types
[1] = LLVMInt32Type ();
5042 AddFunc (module
, "llvm.x86.sse2.psrli.w", ret_type
, arg_types
, 2);
5043 AddFunc (module
, "llvm.x86.sse2.psrai.w", ret_type
, arg_types
, 2);
5044 AddFunc (module
, "llvm.x86.sse2.pslli.w", ret_type
, arg_types
, 2);
5045 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
5046 arg_types
[0] = ret_type
;
5047 arg_types
[1] = LLVMInt32Type ();
5048 AddFunc (module
, "llvm.x86.sse2.psrli.d", ret_type
, arg_types
, 2);
5049 AddFunc (module
, "llvm.x86.sse2.psrai.d", ret_type
, arg_types
, 2);
5050 AddFunc (module
, "llvm.x86.sse2.pslli.d", ret_type
, arg_types
, 2);
5051 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
5052 arg_types
[0] = ret_type
;
5053 arg_types
[1] = LLVMInt32Type ();
5054 AddFunc (module
, "llvm.x86.sse2.psrli.q", ret_type
, arg_types
, 2);
5055 AddFunc (module
, "llvm.x86.sse2.pslli.q", ret_type
, arg_types
, 2);
5058 ret_type
= LLVMInt32Type ();
5059 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
5060 AddFunc (module
, "llvm.x86.sse2.pmovmskb.128", ret_type
, arg_types
, 1);
5063 if (IS_LLVM_MONO_BRANCH
) {
5064 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
5067 /* Load/Store intrinsics */
5068 if (IS_LLVM_MONO_BRANCH
) {
5069 LLVMTypeRef arg_types
[5];
5073 for (i
= 1; i
<= 8; i
*= 2) {
5074 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5075 arg_types
[1] = LLVMInt32Type ();
5076 arg_types
[2] = LLVMInt1Type ();
5077 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
5078 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMIntType (i
* 8), arg_types
, 3, FALSE
));
5080 arg_types
[0] = LLVMIntType (i
* 8);
5081 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
5082 arg_types
[2] = LLVMInt32Type ();
5083 arg_types
[3] = LLVMInt1Type ();
5084 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
5085 LLVMAddFunction (module
, name
, LLVMFunctionType (LLVMVoidType (), arg_types
, 4, FALSE
));
5091 mono_llvm_init (void)
5093 current_cfg_tls_id
= TlsAlloc ();
5097 init_jit_module (void)
5099 MonoJitICallInfo
*info
;
5101 if (jit_module_inited
)
5104 mono_loader_lock ();
5106 if (jit_module_inited
) {
5107 mono_loader_unlock ();
5111 jit_module
.module
= LLVMModuleCreateWithName ("mono");
5113 ee
= mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module
.module
), alloc_cb
, emitted_cb
, exception_cb
);
5115 add_intrinsics (jit_module
.module
);
5117 jit_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5119 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5121 LLVMAddGlobalMapping (ee
, LLVMGetNamedFunction (jit_module
.module
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
5123 jit_module_inited
= TRUE
;
5125 mono_loader_unlock ();
5129 mono_llvm_cleanup (void)
5132 mono_llvm_dispose_ee (ee
);
5134 if (jit_module
.llvm_types
)
5135 g_hash_table_destroy (jit_module
.llvm_types
);
5137 if (aot_module
.module
)
5138 LLVMDisposeModule (aot_module
.module
);
5140 LLVMContextDispose (LLVMGetGlobalContext ());
5144 mono_llvm_create_aot_module (const char *got_symbol
)
5146 /* Delete previous module */
5147 if (aot_module
.plt_entries
)
5148 g_hash_table_destroy (aot_module
.plt_entries
);
5149 if (aot_module
.module
)
5150 LLVMDisposeModule (aot_module
.module
);
5152 memset (&aot_module
, 0, sizeof (aot_module
));
5154 aot_module
.module
= LLVMModuleCreateWithName ("aot");
5155 aot_module
.got_symbol
= got_symbol
;
5157 add_intrinsics (aot_module
.module
);
5161 * We couldn't compute the type of the LLVM global representing the got because
5162 * its size is only known after all the methods have been emitted. So create
5163 * a dummy variable, and replace all uses it with the real got variable when
5164 * its size is known in mono_llvm_emit_aot_module ().
5167 LLVMTypeRef got_type
= LLVMArrayType (IntPtrType (), 0);
5169 aot_module
.got_var
= LLVMAddGlobal (aot_module
.module
, got_type
, "mono_dummy_got");
5170 LLVMSetInitializer (aot_module
.got_var
, LLVMConstNull (got_type
));
5173 /* Add a dummy personality function */
5175 LLVMBasicBlockRef lbb
;
5176 LLVMBuilderRef lbuilder
;
5177 LLVMValueRef personality
;
5179 personality
= LLVMAddFunction (aot_module
.module
, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
5180 LLVMSetLinkage (personality
, LLVMPrivateLinkage
);
5181 lbb
= LLVMAppendBasicBlock (personality
, "BB0");
5182 lbuilder
= LLVMCreateBuilder ();
5183 LLVMPositionBuilderAtEnd (lbuilder
, lbb
);
5184 LLVMBuildRetVoid (lbuilder
);
5187 aot_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
5188 aot_module
.plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
5192 * Emit the aot module into the LLVM bitcode file FILENAME.
5195 mono_llvm_emit_aot_module (const char *filename
, int got_size
)
5197 LLVMTypeRef got_type
;
5198 LLVMValueRef real_got
;
5201 * Create the real got variable and replace all uses of the dummy variable with
5204 got_type
= LLVMArrayType (IntPtrType (), got_size
);
5205 real_got
= LLVMAddGlobal (aot_module
.module
, got_type
, aot_module
.got_symbol
);
5206 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
5207 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
5209 mono_llvm_replace_uses_of (aot_module
.got_var
, real_got
);
5211 mark_as_used (aot_module
.module
, real_got
);
5213 /* Delete the dummy got so it doesn't become a global */
5214 LLVMDeleteGlobal (aot_module
.got_var
);
5220 if (LLVMVerifyModule (aot_module
.module
, LLVMReturnStatusAction
, &verifier_err
)) {
5221 g_assert_not_reached ();
5226 LLVMWriteBitcodeToFile (aot_module
.module
, filename
);
5231 - Emit LLVM IR from the mono IR using the LLVM C API.
5232 - The original arch specific code remains, so we can fall back to it if we run
5233 into something we can't handle.
5237 A partial list of issues:
5238 - Handling of opcodes which can throw exceptions.
5240 In the mono JIT, these are implemented using code like this:
5247 push throw_pos - method
5248 call <exception trampoline>
5250 The problematic part is push throw_pos - method, which cannot be represented
5251 in the LLVM IR, since it does not support label values.
5252 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5253 be implemented in JIT mode ?
5254 -> a possible but slower implementation would use the normal exception
5255 throwing code but it would need to control the placement of the throw code
5256 (it needs to be exactly after the compare+branch).
5257 -> perhaps add a PC offset intrinsics ?
5259 - efficient implementation of .ovf opcodes.
5261 These are currently implemented as:
5262 <ins which sets the condition codes>
5265 Some overflow opcodes are now supported by LLVM SVN.
5267 - exception handling, unwinding.
5268 - SSA is disabled for methods with exception handlers
5269 - How to obtain unwind info for LLVM compiled methods ?
5270 -> this is now solved by converting the unwind info generated by LLVM
5272 - LLVM uses the c++ exception handling framework, while we use our home grown
5273 code, and couldn't use the c++ one:
5274 - its not supported under VC++, other exotic platforms.
5275 - it might be impossible to support filter clauses with it.
5279 The trampolines need a predictable call sequence, since they need to disasm
5280 the calling code to obtain register numbers / offsets.
5282 LLVM currently generates this code in non-JIT mode:
5283 mov -0x98(%rax),%eax
5285 Here, the vtable pointer is lost.
5286 -> solution: use one vtable trampoline per class.
5288 - passing/receiving the IMT pointer/RGCTX.
5289 -> solution: pass them as normal arguments ?
5293 LLVM does not allow the specification of argument registers etc. This means
5294 that all calls are made according to the platform ABI.
5296 - passing/receiving vtypes.
5298 Vtypes passed/received in registers are handled by the front end by using
5299 a signature with scalar arguments, and loading the parts of the vtype into those
5302 Vtypes passed on the stack are handled using the 'byval' attribute.
5306 Supported though alloca, we need to emit the load/store code.
5310 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5311 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5312 This is made easier because the IR is already in SSA form.
5313 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5314 types are frequently used incorrectly.
5319 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5320 append the AOT data structures to that file. For methods which cannot be
5321 handled by LLVM, the normal JIT compiled versions are used.
5324 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5325 * - each bblock should end with a branch
5326 * - setting the return value, making cfg->ret non-volatile
5327 * - avoid some transformations in the JIT which make it harder for us to generate
5329 * - use pointer types to help optimizations.