2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11 #include <mono/metadata/debug-helpers.h>
12 #include <mono/metadata/debug-mono-symfile.h>
13 #include <mono/metadata/mempool-internals.h>
14 #include <mono/metadata/environment.h>
15 #include <mono/metadata/object-internals.h>
16 #include <mono/metadata/abi-details.h>
17 #include <mono/utils/mono-tls.h>
18 #include <mono/utils/mono-dl.h>
19 #include <mono/utils/mono-time.h>
20 #include <mono/utils/freebsd-dwarf.h>
22 #ifndef __STDC_LIMIT_MACROS
23 #define __STDC_LIMIT_MACROS
25 #ifndef __STDC_CONSTANT_MACROS
26 #define __STDC_CONSTANT_MACROS
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
34 #include "aot-compiler.h"
35 #include "mini-llvm.h"
42 extern void *memset(void *, int, size_t);
43 void bzero (void *to
, size_t count
) { memset (to
, 0, count
); }
47 #if LLVM_API_VERSION < 4
48 #error "The version of the mono llvm repository is too old."
51 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
54 * Information associated by mono with LLVM modules.
57 LLVMModuleRef lmodule
;
58 LLVMValueRef throw_icall
, rethrow
, match_exc
, throw_corlib_exception
, resume_eh
;
59 GHashTable
*llvm_types
;
61 const char *got_symbol
;
62 const char *get_method_symbol
;
63 const char *get_unbox_tramp_symbol
;
64 GHashTable
*plt_entries
;
65 GHashTable
*plt_entries_ji
;
66 GHashTable
*method_to_lmethod
;
67 GHashTable
*direct_callables
;
72 GPtrArray
*subprogram_mds
;
74 LLVMExecutionEngineRef ee
;
75 gboolean external_symbols
;
78 LLVMValueRef personality
;
81 MonoAssembly
*assembly
;
83 MonoAotFileInfo aot_info
;
84 const char *jit_got_symbol
;
85 const char *eh_frame_symbol
;
86 LLVMValueRef get_method
, get_unbox_tramp
;
87 LLVMValueRef init_method
, init_method_gshared_mrgctx
, init_method_gshared_this
, init_method_gshared_vtable
;
88 LLVMValueRef code_start
, code_end
;
89 LLVMValueRef inited_var
;
90 int max_inited_idx
, max_method_idx
;
91 gboolean has_jitted_code
;
94 GHashTable
*idx_to_lmethod
;
95 GHashTable
*idx_to_unbox_tramp
;
96 /* Maps a MonoMethod to LLVM instructions representing it */
97 GHashTable
*method_to_callers
;
98 LLVMContextRef context
;
99 LLVMValueRef sentinel_exception
;
100 void *di_builder
, *cu
;
101 GHashTable
*objc_selector_to_var
;
105 * Information associated by the backend with mono basic blocks.
108 LLVMBasicBlockRef bblock
, end_bblock
;
109 LLVMValueRef finally_ind
;
110 gboolean added
, invoke_target
;
112 * If this bblock is the start of a finally clause, this is a list of bblocks it
113 * needs to branch to in ENDFINALLY.
115 GSList
*call_handler_return_bbs
;
117 * If this bblock is the start of a finally clause, this is the bblock that
118 * CALL_HANDLER needs to branch to.
120 LLVMBasicBlockRef call_handler_target_bb
;
121 /* The list of switch statements generated by ENDFINALLY instructions */
122 GSList
*endfinally_switch_ins_list
;
127 * Structure containing emit state
130 MonoMemPool
*mempool
;
132 /* Maps method names to the corresponding LLVMValueRef */
133 GHashTable
*emitted_method_decls
;
136 LLVMValueRef lmethod
;
137 MonoLLVMModule
*module
;
138 LLVMModuleRef lmodule
;
140 int sindex
, default_index
, ex_index
;
141 LLVMBuilderRef builder
;
142 LLVMValueRef
*values
, *addresses
;
143 MonoType
**vreg_cli_types
;
145 MonoMethodSignature
*sig
;
147 GHashTable
*region_to_handler
;
148 GHashTable
*clause_to_handler
;
149 LLVMBuilderRef alloca_builder
;
150 LLVMValueRef last_alloca
;
151 LLVMValueRef rgctx_arg
;
152 LLVMValueRef this_arg
;
153 LLVMTypeRef
*vreg_types
;
155 LLVMTypeRef method_type
;
156 LLVMBasicBlockRef init_bb
, inited_bb
;
158 gboolean
*unreachable
;
160 gboolean has_got_access
;
161 gboolean is_linkonce
;
162 int this_arg_pindex
, rgctx_arg_pindex
;
163 LLVMValueRef imt_rgctx_loc
;
164 GHashTable
*llvm_types
;
166 MonoDebugMethodInfo
*minfo
;
168 /* For every clause, the clauses it is nested in */
171 GHashTable
*exc_meta
;
172 GHashTable
*method_to_callers
;
173 GPtrArray
*phi_values
;
174 GPtrArray
*bblock_list
;
176 GHashTable
*jit_callees
;
177 LLVMValueRef long_bb_break_var
;
183 MonoBasicBlock
*in_bb
;
188 * Instruction metadata
189 * This is the same as ins_info, but LREG != IREG.
197 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
198 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
205 /* keep in sync with the enum in mini.h */
208 #include "mini-ops.h"
213 #if SIZEOF_VOID_P == 4
214 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
216 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
219 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
222 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
224 #define TRACE_FAILURE(msg)
228 #define IS_TARGET_X86 1
230 #define IS_TARGET_X86 0
234 #define IS_TARGET_AMD64 1
236 #define IS_TARGET_AMD64 0
239 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
241 static LLVMIntPredicate cond_to_llvm_cond
[] = {
254 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
267 static MonoNativeTlsKey current_cfg_tls_id
;
269 static MonoLLVMModule aot_module
;
271 static GHashTable
*intrins_id_to_name
;
272 static GHashTable
*intrins_name_to_id
;
274 static void init_jit_module (MonoDomain
*domain
);
276 static void emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
);
277 static LLVMValueRef
emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
);
278 static void emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
);
279 static void emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
);
280 static LLVMValueRef
get_intrinsic (EmitContext
*ctx
, const char *name
);
281 static void decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
);
284 set_failure (EmitContext
*ctx
, const char *message
)
286 TRACE_FAILURE (reason
);
287 ctx
->cfg
->exception_message
= g_strdup (message
);
288 ctx
->cfg
->disable_llvm
= TRUE
;
294 * The LLVM type with width == sizeof (gpointer)
299 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
305 return sizeof (gpointer
) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 return sizeof (gpointer
) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
317 * Return the size of the LLVM representation of the vtype T.
320 get_vtype_size (MonoType
*t
)
324 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
326 /* LLVMArgAsIArgs depends on this since it stores whole words */
327 while (size
< 2 * sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
334 * simd_class_to_llvm_type:
336 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
339 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
341 if (!strcmp (klass
->name
, "Vector2d")) {
342 return LLVMVectorType (LLVMDoubleType (), 2);
343 } else if (!strcmp (klass
->name
, "Vector2l")) {
344 return LLVMVectorType (LLVMInt64Type (), 2);
345 } else if (!strcmp (klass
->name
, "Vector2ul")) {
346 return LLVMVectorType (LLVMInt64Type (), 2);
347 } else if (!strcmp (klass
->name
, "Vector4i")) {
348 return LLVMVectorType (LLVMInt32Type (), 4);
349 } else if (!strcmp (klass
->name
, "Vector4ui")) {
350 return LLVMVectorType (LLVMInt32Type (), 4);
351 } else if (!strcmp (klass
->name
, "Vector4f")) {
352 return LLVMVectorType (LLVMFloatType (), 4);
353 } else if (!strcmp (klass
->name
, "Vector8s")) {
354 return LLVMVectorType (LLVMInt16Type (), 8);
355 } else if (!strcmp (klass
->name
, "Vector8us")) {
356 return LLVMVectorType (LLVMInt16Type (), 8);
357 } else if (!strcmp (klass
->name
, "Vector16sb")) {
358 return LLVMVectorType (LLVMInt8Type (), 16);
359 } else if (!strcmp (klass
->name
, "Vector16b")) {
360 return LLVMVectorType (LLVMInt8Type (), 16);
361 } else if (!strcmp (klass
->name
, "Vector2")) {
362 /* System.Numerics */
363 return LLVMVectorType (LLVMFloatType (), 4);
364 } else if (!strcmp (klass
->name
, "Vector3")) {
365 return LLVMVectorType (LLVMFloatType (), 4);
366 } else if (!strcmp (klass
->name
, "Vector4")) {
367 return LLVMVectorType (LLVMFloatType (), 4);
368 } else if (!strcmp (klass
->name
, "Vector`1")) {
369 MonoType
*etype
= mono_class_get_generic_class (klass
)->context
.class_inst
->type_argv
[0];
370 switch (etype
->type
) {
373 return LLVMVectorType (LLVMInt8Type (), 16);
376 return LLVMVectorType (LLVMInt16Type (), 8);
379 return LLVMVectorType (LLVMInt32Type (), 4);
382 return LLVMVectorType (LLVMInt64Type (), 2);
384 return LLVMVectorType (LLVMFloatType (), 4);
386 return LLVMVectorType (LLVMDoubleType (), 2);
388 g_assert_not_reached ();
392 printf ("%s\n", klass
->name
);
398 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
399 static inline G_GNUC_UNUSED LLVMTypeRef
400 type_to_simd_type (int type
)
404 return LLVMVectorType (LLVMInt8Type (), 16);
406 return LLVMVectorType (LLVMInt16Type (), 8);
408 return LLVMVectorType (LLVMInt32Type (), 4);
410 return LLVMVectorType (LLVMInt64Type (), 2);
412 return LLVMVectorType (LLVMDoubleType (), 2);
414 return LLVMVectorType (LLVMFloatType (), 4);
416 g_assert_not_reached ();
422 create_llvm_type_for_type (MonoLLVMModule
*module
, MonoClass
*klass
)
424 int i
, size
, nfields
, esize
;
425 LLVMTypeRef
*eltypes
;
430 t
= &klass
->byval_arg
;
432 if (mini_type_is_hfa (t
, &nfields
, &esize
)) {
434 * This is needed on arm64 where HFAs are returned in
438 eltypes
= g_new (LLVMTypeRef
, size
);
439 for (i
= 0; i
< size
; ++i
)
440 eltypes
[i
] = esize
== 4 ? LLVMFloatType () : LLVMDoubleType ();
442 size
= get_vtype_size (t
);
444 eltypes
= g_new (LLVMTypeRef
, size
);
445 for (i
= 0; i
< size
; ++i
)
446 eltypes
[i
] = LLVMInt8Type ();
449 name
= mono_type_full_name (&klass
->byval_arg
);
450 ltype
= LLVMStructCreateNamed (module
->context
, name
);
451 LLVMStructSetBody (ltype
, eltypes
, size
, FALSE
);
461 * Return the LLVM type corresponding to T.
464 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
466 t
= mini_get_underlying_type (t
);
470 return LLVMVoidType ();
472 return LLVMInt8Type ();
474 return LLVMInt16Type ();
476 return LLVMInt32Type ();
478 return LLVMInt8Type ();
480 return LLVMInt16Type ();
482 return LLVMInt32Type ();
483 case MONO_TYPE_BOOLEAN
:
484 return LLVMInt8Type ();
487 return LLVMInt64Type ();
489 return LLVMInt16Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT
:
498 case MONO_TYPE_CLASS
:
499 case MONO_TYPE_ARRAY
:
500 case MONO_TYPE_SZARRAY
:
501 case MONO_TYPE_STRING
:
503 return ObjRefType ();
506 /* Because of generic sharing */
507 return ObjRefType ();
508 case MONO_TYPE_GENERICINST
:
509 if (!mono_type_generic_inst_is_valuetype (t
))
510 return ObjRefType ();
512 case MONO_TYPE_VALUETYPE
:
513 case MONO_TYPE_TYPEDBYREF
: {
517 klass
= mono_class_from_mono_type (t
);
519 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
520 return simd_class_to_llvm_type (ctx
, klass
);
523 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
525 ltype
= (LLVMTypeRef
)g_hash_table_lookup (ctx
->module
->llvm_types
, klass
);
527 ltype
= create_llvm_type_for_type (ctx
->module
, klass
);
528 g_hash_table_insert (ctx
->module
->llvm_types
, klass
, ltype
);
534 printf ("X: %d\n", t
->type
);
535 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
536 ctx
->cfg
->disable_llvm
= TRUE
;
544 * Return whenever T is an unsigned int type.
547 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
549 t
= mini_get_underlying_type (t
);
565 * type_to_llvm_arg_type:
567 * Same as type_to_llvm_type, but treat i8/i16 as i32.
570 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
572 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
574 if (ctx
->cfg
->llvm_only
)
578 * This works on all abis except arm64/ios which passes multiple
579 * arguments in one stack slot.
582 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
584 * LLVM generates code which only sets the lower bits, while JITted
585 * code expects all the bits to be set.
587 ptype
= LLVMInt32Type ();
595 * llvm_type_to_stack_type:
597 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
600 static G_GNUC_UNUSED LLVMTypeRef
601 llvm_type_to_stack_type (MonoCompile
*cfg
, LLVMTypeRef type
)
605 if (type
== LLVMInt8Type ())
606 return LLVMInt32Type ();
607 else if (type
== LLVMInt16Type ())
608 return LLVMInt32Type ();
609 else if (!cfg
->r4fp
&& type
== LLVMFloatType ())
610 return LLVMDoubleType ();
616 * regtype_to_llvm_type:
618 * Return the LLVM type corresponding to the regtype C used in instruction
622 regtype_to_llvm_type (char c
)
626 return LLVMInt32Type ();
628 return LLVMInt64Type ();
630 return LLVMDoubleType ();
639 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
642 op_to_llvm_type (int opcode
)
647 return LLVMInt8Type ();
650 return LLVMInt8Type ();
653 return LLVMInt16Type ();
656 return LLVMInt16Type ();
659 return LLVMInt32Type ();
662 return LLVMInt32Type ();
664 return LLVMInt64Type ();
666 return LLVMFloatType ();
668 return LLVMDoubleType ();
670 return LLVMInt64Type ();
672 return LLVMInt32Type ();
674 return LLVMInt64Type ();
679 return LLVMInt8Type ();
684 return LLVMInt16Type ();
686 return LLVMInt32Type ();
689 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
696 return LLVMInt32Type ();
703 return LLVMInt64Type ();
705 printf ("%s\n", mono_inst_name (opcode
));
706 g_assert_not_reached ();
711 #define CLAUSE_START(clause) ((clause)->try_offset)
712 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
715 * load_store_to_llvm_type:
717 * Return the size/sign/zero extension corresponding to the load/store opcode
721 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
727 case OP_LOADI1_MEMBASE
:
728 case OP_STOREI1_MEMBASE_REG
:
729 case OP_STOREI1_MEMBASE_IMM
:
730 case OP_ATOMIC_LOAD_I1
:
731 case OP_ATOMIC_STORE_I1
:
734 return LLVMInt8Type ();
735 case OP_LOADU1_MEMBASE
:
737 case OP_ATOMIC_LOAD_U1
:
738 case OP_ATOMIC_STORE_U1
:
741 return LLVMInt8Type ();
742 case OP_LOADI2_MEMBASE
:
743 case OP_STOREI2_MEMBASE_REG
:
744 case OP_STOREI2_MEMBASE_IMM
:
745 case OP_ATOMIC_LOAD_I2
:
746 case OP_ATOMIC_STORE_I2
:
749 return LLVMInt16Type ();
750 case OP_LOADU2_MEMBASE
:
752 case OP_ATOMIC_LOAD_U2
:
753 case OP_ATOMIC_STORE_U2
:
756 return LLVMInt16Type ();
757 case OP_LOADI4_MEMBASE
:
758 case OP_LOADU4_MEMBASE
:
761 case OP_STOREI4_MEMBASE_REG
:
762 case OP_STOREI4_MEMBASE_IMM
:
763 case OP_ATOMIC_LOAD_I4
:
764 case OP_ATOMIC_STORE_I4
:
765 case OP_ATOMIC_LOAD_U4
:
766 case OP_ATOMIC_STORE_U4
:
768 return LLVMInt32Type ();
769 case OP_LOADI8_MEMBASE
:
771 case OP_STOREI8_MEMBASE_REG
:
772 case OP_STOREI8_MEMBASE_IMM
:
773 case OP_ATOMIC_LOAD_I8
:
774 case OP_ATOMIC_STORE_I8
:
775 case OP_ATOMIC_LOAD_U8
:
776 case OP_ATOMIC_STORE_U8
:
778 return LLVMInt64Type ();
779 case OP_LOADR4_MEMBASE
:
780 case OP_STORER4_MEMBASE_REG
:
781 case OP_ATOMIC_LOAD_R4
:
782 case OP_ATOMIC_STORE_R4
:
784 return LLVMFloatType ();
785 case OP_LOADR8_MEMBASE
:
786 case OP_STORER8_MEMBASE_REG
:
787 case OP_ATOMIC_LOAD_R8
:
788 case OP_ATOMIC_STORE_R8
:
790 return LLVMDoubleType ();
791 case OP_LOAD_MEMBASE
:
793 case OP_STORE_MEMBASE_REG
:
794 case OP_STORE_MEMBASE_IMM
:
795 *size
= sizeof (gpointer
);
796 return IntPtrType ();
798 g_assert_not_reached ();
806 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
809 ovf_op_to_intrins (int opcode
)
813 return "llvm.sadd.with.overflow.i32";
815 return "llvm.uadd.with.overflow.i32";
817 return "llvm.ssub.with.overflow.i32";
819 return "llvm.usub.with.overflow.i32";
821 return "llvm.smul.with.overflow.i32";
823 return "llvm.umul.with.overflow.i32";
825 return "llvm.sadd.with.overflow.i64";
827 return "llvm.uadd.with.overflow.i64";
829 return "llvm.ssub.with.overflow.i64";
831 return "llvm.usub.with.overflow.i64";
833 return "llvm.smul.with.overflow.i64";
835 return "llvm.umul.with.overflow.i64";
837 g_assert_not_reached ();
843 simd_op_to_intrins (int opcode
)
846 #if defined(TARGET_X86) || defined(TARGET_AMD64)
848 return "llvm.x86.sse2.min.pd";
850 return "llvm.x86.sse.min.ps";
852 return "llvm.x86.sse2.max.pd";
854 return "llvm.x86.sse.max.ps";
856 return "llvm.x86.sse3.hadd.pd";
858 return "llvm.x86.sse3.hadd.ps";
860 return "llvm.x86.sse3.hsub.pd";
862 return "llvm.x86.sse3.hsub.ps";
864 return "llvm.x86.sse3.addsub.ps";
866 return "llvm.x86.sse3.addsub.pd";
867 case OP_EXTRACT_MASK
:
868 return "llvm.x86.sse2.pmovmskb.128";
871 return "llvm.x86.sse2.psrli.w";
874 return "llvm.x86.sse2.psrli.d";
877 return "llvm.x86.sse2.psrli.q";
880 return "llvm.x86.sse2.pslli.w";
883 return "llvm.x86.sse2.pslli.d";
886 return "llvm.x86.sse2.pslli.q";
889 return "llvm.x86.sse2.psrai.w";
892 return "llvm.x86.sse2.psrai.d";
894 return "llvm.x86.sse2.padds.b";
896 return "llvm.x86.sse2.padds.w";
898 return "llvm.x86.sse2.psubs.b";
900 return "llvm.x86.sse2.psubs.w";
901 case OP_PADDB_SAT_UN
:
902 return "llvm.x86.sse2.paddus.b";
903 case OP_PADDW_SAT_UN
:
904 return "llvm.x86.sse2.paddus.w";
905 case OP_PSUBB_SAT_UN
:
906 return "llvm.x86.sse2.psubus.b";
907 case OP_PSUBW_SAT_UN
:
908 return "llvm.x86.sse2.psubus.w";
910 return "llvm.x86.sse2.pavg.b";
912 return "llvm.x86.sse2.pavg.w";
914 return "llvm.x86.sse.sqrt.ps";
916 return "llvm.x86.sse2.sqrt.pd";
918 return "llvm.x86.sse.rsqrt.ps";
920 return "llvm.x86.sse.rcp.ps";
922 return "llvm.x86.sse2.cvtdq2pd";
924 return "llvm.x86.sse2.cvtdq2ps";
926 return "llvm.x86.sse2.cvtpd2dq";
928 return "llvm.x86.sse2.cvtps2dq";
930 return "llvm.x86.sse2.cvtpd2ps";
932 return "llvm.x86.sse2.cvtps2pd";
934 return "llvm.x86.sse2.cvttpd2dq";
936 return "llvm.x86.sse2.cvttps2dq";
938 return "llvm.x86.sse2.packsswb.128";
940 return "llvm.x86.sse2.packssdw.128";
942 return "llvm.x86.sse2.packuswb.128";
944 return "llvm.x86.sse41.packusdw";
946 return "llvm.x86.sse2.pmulh.w";
947 case OP_PMULW_HIGH_UN
:
948 return "llvm.x86.sse2.pmulhu.w";
950 return "llvm.x86.sse41.dpps";
953 g_assert_not_reached ();
959 simd_op_to_llvm_type (int opcode
)
961 #if defined(TARGET_X86) || defined(TARGET_AMD64)
965 return type_to_simd_type (MONO_TYPE_R8
);
968 return type_to_simd_type (MONO_TYPE_I8
);
971 return type_to_simd_type (MONO_TYPE_I4
);
976 return type_to_simd_type (MONO_TYPE_I2
);
980 return type_to_simd_type (MONO_TYPE_I1
);
982 return type_to_simd_type (MONO_TYPE_R4
);
985 return type_to_simd_type (MONO_TYPE_I4
);
989 return type_to_simd_type (MONO_TYPE_R8
);
993 return type_to_simd_type (MONO_TYPE_R4
);
994 case OP_EXTRACT_MASK
:
995 return type_to_simd_type (MONO_TYPE_I1
);
1001 return type_to_simd_type (MONO_TYPE_R4
);
1004 return type_to_simd_type (MONO_TYPE_R8
);
1006 g_assert_not_reached ();
1017 * Return the LLVM basic block corresponding to BB.
1019 static LLVMBasicBlockRef
1020 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1022 char bb_name_buf
[128];
1025 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
1026 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
1027 int clause_index
= (mono_get_block_region_notry (ctx
->cfg
, bb
->region
) >> 8) - 1;
1028 sprintf (bb_name_buf
, "EH_CLAUSE%d_BB%d", clause_index
, bb
->block_num
);
1029 bb_name
= bb_name_buf
;
1030 } else if (bb
->block_num
< 256) {
1031 if (!ctx
->module
->bb_names
) {
1032 ctx
->module
->bb_names_len
= 256;
1033 ctx
->module
->bb_names
= g_new0 (char*, ctx
->module
->bb_names_len
);
1035 if (!ctx
->module
->bb_names
[bb
->block_num
]) {
1038 n
= g_strdup_printf ("BB%d", bb
->block_num
);
1039 mono_memory_barrier ();
1040 ctx
->module
->bb_names
[bb
->block_num
] = n
;
1042 bb_name
= ctx
->module
->bb_names
[bb
->block_num
];
1044 sprintf (bb_name_buf
, "BB%d", bb
->block_num
);
1045 bb_name
= bb_name_buf
;
1048 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1049 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
1052 return ctx
->bblocks
[bb
->block_num
].bblock
;
1058 * Return the last LLVM bblock corresponding to BB.
1059 * This might not be equal to the bb returned by get_bb () since we need to generate
1060 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1062 static LLVMBasicBlockRef
1063 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1066 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
1069 static LLVMBasicBlockRef
1070 gen_bb (EmitContext
*ctx
, const char *prefix
)
1074 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
1075 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1081 * Return the target of the patch identified by TYPE and TARGET.
1084 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
1090 memset (&ji
, 0, sizeof (ji
));
1092 ji
.data
.target
= target
;
1094 res
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
, &error
);
1095 mono_error_assert_ok (&error
);
1103 * Emit code to convert the LLVM value V to DTYPE.
1106 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
1108 LLVMTypeRef stype
= LLVMTypeOf (v
);
1110 if (stype
!= dtype
) {
1111 gboolean ext
= FALSE
;
1114 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1116 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1118 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
1122 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
1124 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
1125 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
1128 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1129 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1130 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1131 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1132 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
1133 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1134 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
1135 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
1137 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1138 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1139 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1140 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
1141 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
1142 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
1144 if (mono_arch_is_soft_float ()) {
1145 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
1146 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1147 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
1148 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
1151 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
1152 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1155 LLVMDumpValue (LLVMConstNull (dtype
));
1156 g_assert_not_reached ();
1164 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
1166 return convert_full (ctx
, v
, dtype
, FALSE
);
1170 * emit_volatile_load:
1172 * If vreg is volatile, emit a load from its address.
1175 emit_volatile_load (EmitContext
*ctx
, int vreg
)
1181 // FIXME: This hack is required because we pass the rgctx in a callee saved
1182 // register on arm64 (x15), and llvm might keep the value in that register
1183 // even through the register is marked as 'reserved' inside llvm.
1184 if (ctx
->cfg
->rgctx_var
&& ctx
->cfg
->rgctx_var
->dreg
== vreg
)
1185 v
= mono_llvm_build_load (ctx
->builder
, ctx
->addresses
[vreg
], "", TRUE
);
1187 v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
1189 v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
1191 t
= ctx
->vreg_cli_types
[vreg
];
1192 if (t
&& !t
->byref
) {
1194 * Might have to zero extend since llvm doesn't have
1197 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
1198 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1199 else if (t
->type
== MONO_TYPE_I1
|| t
->type
== MONO_TYPE_I2
)
1200 v
= LLVMBuildSExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1201 else if (t
->type
== MONO_TYPE_U8
)
1202 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
1209 * emit_volatile_store:
1211 * If VREG is volatile, emit a store from its value to its address.
1214 emit_volatile_store (EmitContext
*ctx
, int vreg
)
1216 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1218 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1219 g_assert (ctx
->addresses
[vreg
]);
1220 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1225 sig_to_llvm_sig_no_cinfo (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1227 LLVMTypeRef ret_type
;
1228 LLVMTypeRef
*param_types
= NULL
;
1233 rtype
= mini_get_underlying_type (sig
->ret
);
1234 ret_type
= type_to_llvm_type (ctx
, rtype
);
1238 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1242 param_types
[pindex
++] = ThisType ();
1243 for (i
= 0; i
< sig
->param_count
; ++i
)
1244 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1246 if (!ctx_ok (ctx
)) {
1247 g_free (param_types
);
1251 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1252 g_free (param_types
);
1258 * sig_to_llvm_sig_full:
1260 * Return the LLVM signature corresponding to the mono signature SIG using the
1261 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1264 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
)
1266 LLVMTypeRef ret_type
;
1267 LLVMTypeRef
*param_types
= NULL
;
1269 int i
, j
, pindex
, vret_arg_pindex
= 0;
1270 gboolean vretaddr
= FALSE
;
1274 return sig_to_llvm_sig_no_cinfo (ctx
, sig
);
1276 rtype
= mini_get_underlying_type (sig
->ret
);
1277 ret_type
= type_to_llvm_type (ctx
, rtype
);
1281 switch (cinfo
->ret
.storage
) {
1282 case LLVMArgVtypeInReg
:
1283 /* LLVM models this by returning an aggregate value */
1284 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1285 LLVMTypeRef members
[2];
1287 members
[0] = IntPtrType ();
1288 ret_type
= LLVMStructType (members
, 1, FALSE
);
1289 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgNone
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1291 ret_type
= LLVMVoidType ();
1292 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgInIReg
) {
1293 LLVMTypeRef members
[2];
1295 members
[0] = IntPtrType ();
1296 members
[1] = IntPtrType ();
1297 ret_type
= LLVMStructType (members
, 2, FALSE
);
1299 g_assert_not_reached ();
1302 case LLVMArgVtypeByVal
:
1303 /* Vtype returned normally by val */
1305 case LLVMArgVtypeAsScalar
: {
1306 int size
= mono_class_value_size (mono_class_from_mono_type (rtype
), NULL
);
1307 /* LLVM models this by returning an int */
1308 if (size
< SIZEOF_VOID_P
) {
1309 g_assert (cinfo
->ret
.nslots
== 1);
1310 ret_type
= LLVMIntType (size
* 8);
1312 g_assert (cinfo
->ret
.nslots
== 1 || cinfo
->ret
.nslots
== 2);
1313 ret_type
= LLVMIntType (cinfo
->ret
.nslots
* sizeof (mgreg_t
) * 8);
1317 case LLVMArgAsIArgs
:
1318 ret_type
= LLVMArrayType (IntPtrType (), cinfo
->ret
.nslots
);
1320 case LLVMArgFpStruct
: {
1321 /* Vtype returned as a fp struct */
1322 LLVMTypeRef members
[16];
1324 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1325 for (i
= 0; i
< cinfo
->ret
.nslots
; ++i
)
1326 members
[i
] = cinfo
->ret
.esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1327 ret_type
= LLVMStructType (members
, cinfo
->ret
.nslots
, FALSE
);
1330 case LLVMArgVtypeByRef
:
1331 /* Vtype returned using a hidden argument */
1332 ret_type
= LLVMVoidType ();
1334 case LLVMArgVtypeRetAddr
:
1335 case LLVMArgGsharedvtFixed
:
1336 case LLVMArgGsharedvtFixedVtype
:
1337 case LLVMArgGsharedvtVariable
:
1339 ret_type
= LLVMVoidType ();
1345 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1347 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
) {
1349 * Has to be the first argument because of the sret argument attribute
1350 * FIXME: This might conflict with passing 'this' as the first argument, but
1351 * this is only used on arm64 which has a dedicated struct return register.
1353 cinfo
->vret_arg_pindex
= pindex
;
1354 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->ret
);
1355 if (!ctx_ok (ctx
)) {
1356 g_free (param_types
);
1359 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1362 if (!ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1363 cinfo
->rgctx_arg_pindex
= pindex
;
1364 param_types
[pindex
] = ctx
->module
->ptr_type
;
1367 if (cinfo
->imt_arg
) {
1368 cinfo
->imt_arg_pindex
= pindex
;
1369 param_types
[pindex
] = ctx
->module
->ptr_type
;
1373 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1374 vret_arg_pindex
= pindex
;
1375 if (cinfo
->vret_arg_index
== 1) {
1376 /* Add the slots consumed by the first argument */
1377 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1378 switch (ainfo
->storage
) {
1379 case LLVMArgVtypeInReg
:
1380 for (j
= 0; j
< 2; ++j
) {
1381 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1390 cinfo
->vret_arg_pindex
= vret_arg_pindex
;
1393 if (vretaddr
&& vret_arg_pindex
== pindex
)
1394 param_types
[pindex
++] = IntPtrType ();
1396 cinfo
->this_arg_pindex
= pindex
;
1397 param_types
[pindex
++] = ThisType ();
1398 cinfo
->args
[0].pindex
= cinfo
->this_arg_pindex
;
1400 if (vretaddr
&& vret_arg_pindex
== pindex
)
1401 param_types
[pindex
++] = IntPtrType ();
1402 for (i
= 0; i
< sig
->param_count
; ++i
) {
1403 LLVMArgInfo
*ainfo
= &cinfo
->args
[i
+ sig
->hasthis
];
1405 if (vretaddr
&& vret_arg_pindex
== pindex
)
1406 param_types
[pindex
++] = IntPtrType ();
1407 ainfo
->pindex
= pindex
;
1409 switch (ainfo
->storage
) {
1410 case LLVMArgVtypeInReg
:
1411 for (j
= 0; j
< 2; ++j
) {
1412 switch (ainfo
->pair_storage
[j
]) {
1414 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
1419 g_assert_not_reached ();
1423 case LLVMArgVtypeByVal
:
1424 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1427 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1430 case LLVMArgAsIArgs
:
1431 param_types
[pindex
] = LLVMArrayType (IntPtrType (), ainfo
->nslots
);
1434 case LLVMArgVtypeByRef
:
1435 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1438 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1441 case LLVMArgAsFpArgs
: {
1444 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1445 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
1446 param_types
[pindex
++] = LLVMDoubleType ();
1447 for (j
= 0; j
< ainfo
->nslots
; ++j
)
1448 param_types
[pindex
++] = ainfo
->esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1451 case LLVMArgVtypeAsScalar
:
1452 g_assert_not_reached ();
1454 case LLVMArgGsharedvtFixed
:
1455 case LLVMArgGsharedvtFixedVtype
:
1456 param_types
[pindex
++] = LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0);
1458 case LLVMArgGsharedvtVariable
:
1459 param_types
[pindex
++] = LLVMPointerType (IntPtrType (), 0);
1462 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1466 if (!ctx_ok (ctx
)) {
1467 g_free (param_types
);
1470 if (vretaddr
&& vret_arg_pindex
== pindex
)
1471 param_types
[pindex
++] = IntPtrType ();
1472 if (ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1473 /* Pass the rgctx as the last argument */
1474 cinfo
->rgctx_arg_pindex
= pindex
;
1475 param_types
[pindex
] = ctx
->module
->ptr_type
;
1479 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1480 g_free (param_types
);
1486 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1488 return sig_to_llvm_sig_full (ctx
, sig
, NULL
);
1492 * LLVMFunctionType1:
1494 * Create an LLVM function type from the arguments.
1496 static G_GNUC_UNUSED LLVMTypeRef
1497 LLVMFunctionType0 (LLVMTypeRef ReturnType
,
1500 return LLVMFunctionType (ReturnType
, NULL
, 0, IsVarArg
);
1504 * LLVMFunctionType1:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType1 (LLVMTypeRef ReturnType
,
1510 LLVMTypeRef ParamType1
,
1513 LLVMTypeRef param_types
[1];
1515 param_types
[0] = ParamType1
;
1517 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1521 * LLVMFunctionType2:
1523 * Create an LLVM function type from the arguments.
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType2 (LLVMTypeRef ReturnType
,
1527 LLVMTypeRef ParamType1
,
1528 LLVMTypeRef ParamType2
,
1531 LLVMTypeRef param_types
[2];
1533 param_types
[0] = ParamType1
;
1534 param_types
[1] = ParamType2
;
1536 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1540 * LLVMFunctionType3:
1542 * Create an LLVM function type from the arguments.
1544 static G_GNUC_UNUSED LLVMTypeRef
1545 LLVMFunctionType3 (LLVMTypeRef ReturnType
,
1546 LLVMTypeRef ParamType1
,
1547 LLVMTypeRef ParamType2
,
1548 LLVMTypeRef ParamType3
,
1551 LLVMTypeRef param_types
[3];
1553 param_types
[0] = ParamType1
;
1554 param_types
[1] = ParamType2
;
1555 param_types
[2] = ParamType3
;
1557 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1560 static G_GNUC_UNUSED LLVMTypeRef
1561 LLVMFunctionType5 (LLVMTypeRef ReturnType
,
1562 LLVMTypeRef ParamType1
,
1563 LLVMTypeRef ParamType2
,
1564 LLVMTypeRef ParamType3
,
1565 LLVMTypeRef ParamType4
,
1566 LLVMTypeRef ParamType5
,
1569 LLVMTypeRef param_types
[5];
1571 param_types
[0] = ParamType1
;
1572 param_types
[1] = ParamType2
;
1573 param_types
[2] = ParamType3
;
1574 param_types
[3] = ParamType4
;
1575 param_types
[4] = ParamType5
;
1577 return LLVMFunctionType (ReturnType
, param_types
, 5, IsVarArg
);
1583 * Create an LLVM builder and remember it so it can be freed later.
1585 static LLVMBuilderRef
1586 create_builder (EmitContext
*ctx
)
1588 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1590 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1596 get_aotconst_name (MonoJumpInfoType type
, gconstpointer data
, int got_offset
)
1601 case MONO_PATCH_INFO_INTERNAL_METHOD
:
1602 name
= g_strdup_printf ("jit_icall_%s", data
);
1604 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX
: {
1605 MonoJumpInfoRgctxEntry
*entry
= (MonoJumpInfoRgctxEntry
*)data
;
1606 name
= g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry
->info_type
));
1610 name
= g_strdup_printf ("%s_%d", mono_ji_type_to_string (type
), got_offset
);
1618 get_aotconst_typed (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
, LLVMTypeRef llvm_type
)
1622 LLVMValueRef indexes
[2];
1623 LLVMValueRef got_entry_addr
, load
;
1624 LLVMBuilderRef builder
= ctx
->builder
;
1629 MonoJumpInfo tmp_ji
;
1631 tmp_ji
.data
.target
= data
;
1633 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1635 ji
->next
= cfg
->patch_info
;
1636 cfg
->patch_info
= ji
;
1638 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
1639 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
1641 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1642 * explicitly initialize it.
1644 if (!mono_aot_is_shared_got_offset (got_offset
)) {
1645 //mono_print_ji (ji);
1647 ctx
->has_got_access
= TRUE
;
1650 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1651 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
1652 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1654 name
= get_aotconst_name (type
, data
, got_offset
);
1656 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1657 load
= convert (ctx
, load
, llvm_type
);
1658 LLVMSetValueName (load
, name
? name
: "");
1660 load
= LLVMBuildLoad (builder
, got_entry_addr
, name
? name
: "");
1663 //set_invariant_load_flag (load);
1669 get_aotconst (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
)
1671 return get_aotconst_typed (ctx
, type
, data
, NULL
);
1675 get_callee (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1677 LLVMValueRef callee
;
1679 if (ctx
->llvm_only
) {
1680 callee_name
= mono_aot_get_direct_call_symbol (type
, data
);
1682 /* Directly callable */
1684 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->direct_callables
, callee_name
);
1686 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1688 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1690 g_hash_table_insert (ctx
->module
->direct_callables
, (char*)callee_name
, callee
);
1692 /* LLVMTypeRef's are uniqued */
1693 if (LLVMGetElementType (LLVMTypeOf (callee
)) != llvm_sig
)
1694 return LLVMConstBitCast (callee
, LLVMPointerType (llvm_sig
, 0));
1696 g_free (callee_name
);
1702 * Calls are made through the GOT.
1704 return get_aotconst_typed (ctx
, type
, data
, LLVMPointerType (llvm_sig
, 0));
1706 MonoJumpInfo
*ji
= NULL
;
1708 callee_name
= mono_aot_get_plt_symbol (type
, data
);
1712 if (ctx
->cfg
->compile_aot
)
1713 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1714 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1717 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->plt_entries
, callee_name
);
1719 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1721 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1723 g_hash_table_insert (ctx
->module
->plt_entries
, (char*)callee_name
, callee
);
1726 if (ctx
->cfg
->compile_aot
) {
1727 ji
= g_new0 (MonoJumpInfo
, 1);
1729 ji
->data
.target
= data
;
1731 g_hash_table_insert (ctx
->module
->plt_entries_ji
, ji
, callee
);
1739 emit_jit_callee (EmitContext
*ctx
, const char *name
, LLVMTypeRef llvm_sig
, gpointer target
)
1741 #if LLVM_API_VERSION > 100
1742 LLVMValueRef tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
1743 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
1744 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
1745 LLVMValueRef callee
= LLVMBuildLoad (ctx
->builder
, tramp_var
, "");
1748 LLVMValueRef callee
= LLVMAddFunction (ctx
->lmodule
, "", llvm_sig
);
1749 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
1755 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1757 MonoMethodHeader
*header
= cfg
->header
;
1758 MonoExceptionClause
*clause
;
1762 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1763 return (bb
->region
>> 8) - 1;
1766 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1767 clause
= &header
->clauses
[i
];
1769 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1776 static MonoExceptionClause
*
1777 get_most_deep_clause (MonoCompile
*cfg
, EmitContext
*ctx
, MonoBasicBlock
*bb
)
1779 if (bb
== cfg
->bb_init
)
1781 // Since they're sorted by nesting we just need
1782 // the first one that the bb is a member of
1783 for (int i
= 0; i
< cfg
->header
->num_clauses
; i
++) {
1784 MonoExceptionClause
*curr
= &cfg
->header
->clauses
[i
];
1786 if (MONO_OFFSET_IN_CLAUSE (curr
, bb
->real_offset
))
1794 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1796 LLVMValueRef md_arg
;
1799 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1800 md_arg
= LLVMMDString ("mono", 4);
1801 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1805 set_invariant_load_flag (LLVMValueRef v
)
1807 LLVMValueRef md_arg
;
1809 const char *flag_name
;
1811 // FIXME: Cache this
1812 flag_name
= "invariant.load";
1813 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1814 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
1815 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1821 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1825 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1827 MonoCompile
*cfg
= ctx
->cfg
;
1828 LLVMValueRef lcall
= NULL
;
1829 LLVMBuilderRef builder
= *builder_ref
;
1830 MonoExceptionClause
*clause
;
1832 if (ctx
->llvm_only
) {
1833 clause
= get_most_deep_clause (cfg
, ctx
, bb
);
1836 g_assert (clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1839 * Have to use an invoke instead of a call, branching to the
1840 * handler bblock of the clause containing this bblock.
1842 intptr_t key
= CLAUSE_END(clause
);
1844 LLVMBasicBlockRef lpad_bb
= (LLVMBasicBlockRef
)g_hash_table_lookup (ctx
->exc_meta
, (gconstpointer
)key
);
1846 // FIXME: Find the one that has the lowest end bound for the right start address
1847 // FIXME: Finally + nesting
1850 LLVMBasicBlockRef noex_bb
= gen_bb (ctx
, "CALL_NOEX_BB");
1853 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, lpad_bb
, "");
1855 builder
= ctx
->builder
= create_builder (ctx
);
1856 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1858 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1862 int clause_index
= get_handler_clause (cfg
, bb
);
1864 if (clause_index
!= -1) {
1865 MonoMethodHeader
*header
= cfg
->header
;
1866 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1867 MonoBasicBlock
*tblock
;
1868 LLVMBasicBlockRef ex_bb
, noex_bb
;
1871 * Have to use an invoke instead of a call, branching to the
1872 * handler bblock of the clause containing this bblock.
1875 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1877 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1880 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1882 ex_bb
= get_bb (ctx
, tblock
);
1884 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1887 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1889 builder
= ctx
->builder
= create_builder (ctx
);
1890 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1892 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1897 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1898 ctx
->builder
= builder
;
1902 *builder_ref
= ctx
->builder
;
1908 emit_load_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, LLVMValueRef base
, const char *name
, gboolean is_faulting
, BarrierKind barrier
)
1910 const char *intrins_name
;
1911 LLVMValueRef args
[16], res
;
1912 LLVMTypeRef addr_type
;
1913 gboolean use_intrinsics
= TRUE
;
1915 #if LLVM_API_VERSION > 100
1916 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
1917 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1920 cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
1921 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
1922 *builder_ref
= ctx
->builder
;
1923 use_intrinsics
= FALSE
;
1927 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
1928 LLVMAtomicOrdering ordering
;
1931 case LLVM_BARRIER_NONE
:
1932 ordering
= LLVMAtomicOrderingNotAtomic
;
1934 case LLVM_BARRIER_ACQ
:
1935 ordering
= LLVMAtomicOrderingAcquire
;
1937 case LLVM_BARRIER_SEQ
:
1938 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
1941 g_assert_not_reached ();
1946 * We handle loads which can fault by calling a mono specific intrinsic
1947 * using an invoke, so they are handled properly inside try blocks.
1948 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1949 * are marked with IntrReadArgMem.
1953 intrins_name
= "llvm.mono.load.i8.p0i8";
1956 intrins_name
= "llvm.mono.load.i16.p0i16";
1959 intrins_name
= "llvm.mono.load.i32.p0i32";
1962 intrins_name
= "llvm.mono.load.i64.p0i64";
1965 g_assert_not_reached ();
1968 addr_type
= LLVMTypeOf (addr
);
1969 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1970 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1973 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1974 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1975 args
[3] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
1976 res
= emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 4);
1978 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1979 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1980 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1981 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1988 * We emit volatile loads for loads which can fault, because otherwise
1989 * LLVM will generate invalid code when encountering a load from a
1992 if (barrier
!= LLVM_BARRIER_NONE
)
1993 res
= mono_llvm_build_atomic_load (*builder_ref
, addr
, name
, is_faulting
, size
, barrier
);
1995 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1997 /* Mark it with a custom metadata */
2000 set_metadata_flag (res, "mono.faulting.load");
2008 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
2010 return emit_load_general (ctx
, bb
, builder_ref
, size
, addr
, addr
, name
, is_faulting
, LLVM_BARRIER_NONE
);
2014 emit_store_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
, BarrierKind barrier
)
2016 const char *intrins_name
;
2017 LLVMValueRef args
[16];
2018 gboolean use_intrinsics
= TRUE
;
2020 #if LLVM_API_VERSION > 100
2021 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
2022 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2023 LLVMValueRef cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
2024 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
2025 *builder_ref
= ctx
->builder
;
2026 use_intrinsics
= FALSE
;
2030 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
2031 LLVMAtomicOrdering ordering
;
2034 case LLVM_BARRIER_NONE
:
2035 ordering
= LLVMAtomicOrderingNotAtomic
;
2037 case LLVM_BARRIER_REL
:
2038 ordering
= LLVMAtomicOrderingRelease
;
2040 case LLVM_BARRIER_SEQ
:
2041 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
2044 g_assert_not_reached ();
2050 intrins_name
= "llvm.mono.store.i8.p0i8";
2053 intrins_name
= "llvm.mono.store.i16.p0i16";
2056 intrins_name
= "llvm.mono.store.i32.p0i32";
2059 intrins_name
= "llvm.mono.store.i64.p0i64";
2062 g_assert_not_reached ();
2065 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
2066 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
2067 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2072 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2073 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2074 args
[4] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2075 emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 5);
2077 if (barrier
!= LLVM_BARRIER_NONE
)
2078 mono_llvm_build_aligned_store (*builder_ref
, value
, addr
, barrier
, size
);
2080 mono_llvm_build_store (*builder_ref
, value
, addr
, is_faulting
, barrier
);
2085 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
)
2087 emit_store_general (ctx
, bb
, builder_ref
, size
, value
, addr
, base
, is_faulting
, LLVM_BARRIER_NONE
);
2091 * emit_cond_system_exception:
2093 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2094 * Might set the ctx exception.
2097 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
2099 LLVMBasicBlockRef ex_bb
, ex2_bb
= NULL
, noex_bb
;
2100 LLVMBuilderRef builder
;
2101 MonoClass
*exc_class
;
2102 LLVMValueRef args
[2];
2103 LLVMValueRef callee
;
2104 gboolean no_pc
= FALSE
;
2106 if (IS_TARGET_AMD64
)
2107 /* Some platforms don't require the pc argument */
2110 ex_bb
= gen_bb (ctx
, "EX_BB");
2112 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2113 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2115 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
2117 exc_class
= mono_class_load_from_name (mono_get_corlib (), "System", exc_type
);
2119 /* Emit exception throwing code */
2120 ctx
->builder
= builder
= create_builder (ctx
);
2121 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
2123 if (ctx
->cfg
->llvm_only
) {
2124 static LLVMTypeRef sig
;
2127 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2128 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mono_llvm_throw_corlib_exception");
2130 LLVMBuildBr (builder
, ex2_bb
);
2132 ctx
->builder
= builder
= create_builder (ctx
);
2133 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2135 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2136 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2137 LLVMBuildUnreachable (builder
);
2139 ctx
->builder
= builder
= create_builder (ctx
);
2140 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2142 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2148 callee
= ctx
->module
->throw_corlib_exception
;
2151 const char *icall_name
;
2154 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2156 sig
= LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE
);
2157 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
2159 if (ctx
->cfg
->compile_aot
) {
2160 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2163 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2164 * - On x86, LLVM generated code doesn't push the arguments
2165 * - The trampoline takes the throw address as an arguments, not a pc offset.
2167 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2168 callee
= emit_jit_callee (ctx
, "llvm_throw_corlib_exception_trampoline", sig
, target
);
2170 #if LLVM_API_VERSION > 100
2172 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2173 * added by emit_jit_callee ().
2175 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2176 LLVMBuildBr (builder
, ex2_bb
);
2179 ctx
->builder
= builder
= create_builder (ctx
);
2180 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2182 mono_memory_barrier ();
2183 ctx
->module
->throw_corlib_exception
= callee
;
2188 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2191 * The LLVM mono branch contains changes so a block address can be passed as an
2192 * argument to a call.
2195 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2197 args
[1] = LLVMBlockAddress (ctx
->lmethod
, ex_bb
);
2198 emit_call (ctx
, bb
, &builder
, callee
, args
, 2);
2201 LLVMBuildUnreachable (builder
);
2203 ctx
->builder
= builder
= create_builder (ctx
);
2204 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2206 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2213 * emit_args_to_vtype:
2215 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2218 emit_args_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
)
2220 int j
, size
, nslots
;
2222 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
2224 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2225 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2228 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2229 nslots
= ainfo
->nslots
;
2233 for (j
= 0; j
< nslots
; ++j
) {
2234 LLVMValueRef index
[2], addr
, daddr
;
2235 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2236 LLVMTypeRef part_type
;
2238 while (part_size
!= 1 && part_size
!= 2 && part_size
!= 4 && part_size
< 8)
2241 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2244 switch (ainfo
->pair_storage
[j
]) {
2245 case LLVMArgInIReg
: {
2246 part_type
= LLVMIntType (part_size
* 8);
2247 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2248 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2249 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2251 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2252 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2253 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2255 LLVMBuildStore (builder
, convert (ctx
, args
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
2258 case LLVMArgInFPReg
: {
2259 LLVMTypeRef arg_type
;
2261 if (ainfo
->esize
== 8)
2262 arg_type
= LLVMDoubleType ();
2264 arg_type
= LLVMFloatType ();
2266 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2267 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2268 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2269 LLVMBuildStore (builder
, args
[j
], addr
);
2275 g_assert_not_reached ();
2278 size
-= sizeof (gpointer
);
2283 * emit_vtype_to_args:
2285 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2286 * into ARGS, and the number of arguments into NARGS.
2289 emit_vtype_to_args (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
, guint32
*nargs
)
2292 int j
, size
, nslots
;
2293 LLVMTypeRef arg_type
;
2295 size
= get_vtype_size (t
);
2297 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
)))
2298 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2300 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2301 nslots
= ainfo
->nslots
;
2304 for (j
= 0; j
< nslots
; ++j
) {
2305 LLVMValueRef index
[2], addr
, daddr
;
2306 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2308 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2311 switch (ainfo
->pair_storage
[j
]) {
2313 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2314 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2315 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2317 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2318 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2319 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2321 args
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
2323 case LLVMArgInFPReg
:
2324 if (ainfo
->esize
== 8)
2325 arg_type
= LLVMDoubleType ();
2327 arg_type
= LLVMFloatType ();
2328 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2329 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2330 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2331 args
[pindex
++] = LLVMBuildLoad (builder
, addr
, "");
2336 g_assert_not_reached ();
2338 size
-= sizeof (gpointer
);
2345 build_alloca_llvm_type_name (EmitContext
*ctx
, LLVMTypeRef t
, int align
, const char *name
)
2348 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2349 * get executed every time control reaches them.
2351 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
2353 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, t
, NULL
, align
, name
);
2354 return ctx
->last_alloca
;
2358 build_alloca_llvm_type (EmitContext
*ctx
, LLVMTypeRef t
, int align
)
2360 return build_alloca_llvm_type_name (ctx
, t
, align
, "");
2364 build_alloca (EmitContext
*ctx
, MonoType
*t
)
2366 MonoClass
*k
= mono_class_from_mono_type (t
);
2369 g_assert (!mini_is_gsharedvt_variable_type (t
));
2371 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
2374 align
= mono_class_min_align (k
);
2376 /* Sometimes align is not a power of 2 */
2377 while (mono_is_power_of_two (align
) == -1)
2380 return build_alloca_llvm_type (ctx
, type_to_llvm_type (ctx
, t
), align
);
2384 emit_gsharedvt_ldaddr (EmitContext
*ctx
, int vreg
)
2388 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2390 MonoCompile
*cfg
= ctx
->cfg
;
2391 LLVMBuilderRef builder
= ctx
->builder
;
2392 LLVMValueRef offset
, offset_var
;
2393 LLVMValueRef info_var
= ctx
->values
[cfg
->gsharedvt_info_var
->dreg
];
2394 LLVMValueRef locals_var
= ctx
->values
[cfg
->gsharedvt_locals_var
->dreg
];
2398 g_assert (info_var
);
2399 g_assert (locals_var
);
2401 int idx
= cfg
->gsharedvt_vreg_to_idx
[vreg
] - 1;
2403 offset
= LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo
, entries
) + (idx
* sizeof (gpointer
)), FALSE
);
2404 ptr
= LLVMBuildAdd (builder
, convert (ctx
, info_var
, IntPtrType ()), convert (ctx
, offset
, IntPtrType ()), "");
2406 name
= g_strdup_printf ("gsharedvt_local_%d_offset", vreg
);
2407 offset_var
= LLVMBuildLoad (builder
, convert (ctx
, ptr
, LLVMPointerType (LLVMInt32Type (), 0)), name
);
2409 return LLVMBuildAdd (builder
, convert (ctx
, locals_var
, IntPtrType ()), convert (ctx
, offset_var
, IntPtrType ()), "");
2413 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2416 mark_as_used (MonoLLVMModule
*module
, LLVMValueRef global
)
2419 module
->used
= g_ptr_array_sized_new (16);
2420 g_ptr_array_add (module
->used
, global
);
2424 emit_llvm_used (MonoLLVMModule
*module
)
2426 LLVMModuleRef lmodule
= module
->lmodule
;
2427 LLVMTypeRef used_type
;
2428 LLVMValueRef used
, *used_elem
;
2434 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module
->used
->len
);
2435 used
= LLVMAddGlobal (lmodule
, used_type
, "llvm.used");
2436 used_elem
= g_new0 (LLVMValueRef
, module
->used
->len
);
2437 for (i
= 0; i
< module
->used
->len
; ++i
)
2438 used_elem
[i
] = LLVMConstBitCast ((LLVMValueRef
)g_ptr_array_index (module
->used
, i
), LLVMPointerType (LLVMInt8Type (), 0));
2439 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem
, module
->used
->len
));
2440 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
2441 LLVMSetSection (used
, "llvm.metadata");
2447 * Emit a function mapping method indexes to their code
2450 emit_get_method (MonoLLVMModule
*module
)
2452 LLVMModuleRef lmodule
= module
->lmodule
;
2453 LLVMValueRef func
, switch_ins
, m
;
2454 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
, code_start_bb
, code_end_bb
;
2455 LLVMBasicBlockRef
*bbs
;
2457 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2462 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2463 * but generating code seems safer.
2465 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2466 func
= LLVMAddFunction (lmodule
, module
->get_method_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2467 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2468 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2469 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2470 module
->get_method
= func
;
2472 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2475 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2476 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2477 * then we will have to find another solution.
2480 name
= g_strdup_printf ("BB_CODE_START");
2481 code_start_bb
= LLVMAppendBasicBlock (func
, name
);
2483 LLVMPositionBuilderAtEnd (builder
, code_start_bb
);
2484 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_start
, rtype
, ""));
2486 name
= g_strdup_printf ("BB_CODE_END");
2487 code_end_bb
= LLVMAppendBasicBlock (func
, name
);
2489 LLVMPositionBuilderAtEnd (builder
, code_end_bb
);
2490 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_end
, rtype
, ""));
2492 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2493 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2494 name
= g_strdup_printf ("BB_%d", i
);
2495 bb
= LLVMAppendBasicBlock (func
, name
);
2499 LLVMPositionBuilderAtEnd (builder
, bb
);
2501 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2503 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2505 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2508 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2509 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2510 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2512 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2514 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2515 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2516 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2517 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2518 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2521 mark_as_used (module
, func
);
2523 LLVMDisposeBuilder (builder
);
2527 * emit_get_unbox_tramp:
2529 * Emit a function mapping method indexes to their unbox trampoline
2532 emit_get_unbox_tramp (MonoLLVMModule
*module
)
2534 LLVMModuleRef lmodule
= module
->lmodule
;
2535 LLVMValueRef func
, switch_ins
, m
;
2536 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
;
2537 LLVMBasicBlockRef
*bbs
;
2539 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2543 /* Similar to emit_get_method () */
2545 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2546 func
= LLVMAddFunction (lmodule
, module
->get_unbox_tramp_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2547 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2548 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2549 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2550 module
->get_unbox_tramp
= func
;
2552 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2554 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2555 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2556 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2560 name
= g_strdup_printf ("BB_%d", i
);
2561 bb
= LLVMAppendBasicBlock (func
, name
);
2565 LLVMPositionBuilderAtEnd (builder
, bb
);
2567 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2570 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2571 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2572 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2574 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2576 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2577 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2578 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2582 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2585 mark_as_used (module
, func
);
2586 LLVMDisposeBuilder (builder
);
2589 /* Add a function to mark the beginning of LLVM code */
2591 emit_llvm_code_start (MonoLLVMModule
*module
)
2593 LLVMModuleRef lmodule
= module
->lmodule
;
2595 LLVMBasicBlockRef entry_bb
;
2596 LLVMBuilderRef builder
;
2598 func
= LLVMAddFunction (lmodule
, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2599 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2600 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2601 module
->code_start
= func
;
2602 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2603 builder
= LLVMCreateBuilder ();
2604 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2605 LLVMBuildRetVoid (builder
);
2606 LLVMDisposeBuilder (builder
);
2610 emit_init_icall_wrapper (MonoLLVMModule
*module
, const char *name
, const char *icall_name
, int subtype
)
2612 LLVMModuleRef lmodule
= module
->lmodule
;
2613 LLVMValueRef func
, indexes
[2], got_entry_addr
, args
[16], callee
;
2614 LLVMBasicBlockRef entry_bb
;
2615 LLVMBuilderRef builder
;
2622 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
));
2623 sig
= LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE
);
2628 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE
));
2629 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE
);
2632 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE
));
2633 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE
);
2636 g_assert_not_reached ();
2638 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2639 LLVMAddFunctionAttr (func
, LLVMNoInlineAttribute
);
2640 mono_llvm_set_preserveall_cc (func
);
2641 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2642 builder
= LLVMCreateBuilder ();
2643 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2646 ji
= g_new0 (MonoJumpInfo
, 1);
2647 ji
->type
= MONO_PATCH_INFO_AOT_MODULE
;
2648 ji
= mono_aot_patch_info_dup (ji
);
2649 got_offset
= mono_aot_get_got_offset (ji
);
2650 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2651 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2652 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2653 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2654 args
[0] = LLVMBuildPtrToInt (builder
, LLVMBuildLoad (builder
, got_entry_addr
, ""), IntPtrType (), "");
2655 args
[1] = LLVMGetParam (func
, 0);
2657 args
[2] = LLVMGetParam (func
, 1);
2659 ji
= g_new0 (MonoJumpInfo
, 1);
2660 ji
->type
= MONO_PATCH_INFO_INTERNAL_METHOD
;
2661 ji
->data
.name
= icall_name
;
2662 ji
= mono_aot_patch_info_dup (ji
);
2663 got_offset
= mono_aot_get_got_offset (ji
);
2664 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2665 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2666 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2667 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2668 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
2669 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
2670 LLVMBuildCall (builder
, callee
, args
, LLVMCountParamTypes (sig
), "");
2672 // Set the inited flag
2673 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2674 indexes
[1] = LLVMGetParam (func
, 0);
2675 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt8Type (), 1, FALSE
), LLVMBuildGEP (builder
, module
->inited_var
, indexes
, 2, ""));
2677 LLVMBuildRetVoid (builder
);
2679 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
2680 LLVMDisposeBuilder (builder
);
2685 * Emit wrappers around the C icalls used to initialize llvm methods, to
2686 * make the calling code smaller and to enable usage of the llvm
2687 * PreserveAll calling convention.
2690 emit_init_icall_wrappers (MonoLLVMModule
*module
)
2692 module
->init_method
= emit_init_icall_wrapper (module
, "init_method", "mono_aot_init_llvm_method", 0);
2693 module
->init_method_gshared_mrgctx
= emit_init_icall_wrapper (module
, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2694 module
->init_method_gshared_this
= emit_init_icall_wrapper (module
, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2695 module
->init_method_gshared_vtable
= emit_init_icall_wrapper (module
, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2699 emit_llvm_code_end (MonoLLVMModule
*module
)
2701 LLVMModuleRef lmodule
= module
->lmodule
;
2703 LLVMBasicBlockRef entry_bb
;
2704 LLVMBuilderRef builder
;
2706 func
= LLVMAddFunction (lmodule
, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2707 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2708 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2709 module
->code_end
= func
;
2710 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2711 builder
= LLVMCreateBuilder ();
2712 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2713 LLVMBuildRetVoid (builder
);
2714 LLVMDisposeBuilder (builder
);
2718 emit_div_check (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoBasicBlock
*bb
, MonoInst
*ins
, LLVMValueRef lhs
, LLVMValueRef rhs
)
2720 gboolean need_div_check
= ctx
->cfg
->backend
->need_div_check
;
2723 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2724 need_div_check
= TRUE
;
2726 if (!need_div_check
)
2729 switch (ins
->opcode
) {
2742 case OP_IDIV_UN_IMM
:
2743 case OP_LDIV_UN_IMM
:
2744 case OP_IREM_UN_IMM
:
2745 case OP_LREM_UN_IMM
: {
2747 gboolean is_signed
= (ins
->opcode
== OP_IDIV
|| ins
->opcode
== OP_LDIV
|| ins
->opcode
== OP_IREM
|| ins
->opcode
== OP_LREM
||
2748 ins
->opcode
== OP_IDIV_IMM
|| ins
->opcode
== OP_LDIV_IMM
|| ins
->opcode
== OP_IREM_IMM
|| ins
->opcode
== OP_LREM_IMM
);
2750 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), 0, FALSE
), "");
2751 emit_cond_system_exception (ctx
, bb
, "DivideByZeroException", cmp
);
2754 builder
= ctx
->builder
;
2756 /* b == -1 && a == 0x80000000 */
2758 LLVMValueRef c
= (LLVMTypeOf (lhs
) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs
), 0x80000000, FALSE
) : LLVMConstInt (LLVMTypeOf (lhs
), 0x8000000000000000LL
, FALSE
);
2759 LLVMValueRef cond1
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), -1, FALSE
), "");
2760 LLVMValueRef cond2
= LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, c
, "");
2762 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, LLVMBuildAnd (builder
, cond1
, cond2
, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE
), "");
2763 emit_cond_system_exception (ctx
, bb
, "OverflowException", cmp
);
2766 builder
= ctx
->builder
;
2778 * Emit code to initialize the GOT slots used by the method.
2781 emit_init_method (EmitContext
*ctx
)
2783 LLVMValueRef indexes
[16], args
[16], callee
;
2784 LLVMValueRef inited_var
, cmp
, call
;
2785 LLVMBasicBlockRef inited_bb
, notinited_bb
;
2786 LLVMBuilderRef builder
= ctx
->builder
;
2787 MonoCompile
*cfg
= ctx
->cfg
;
2789 ctx
->module
->max_inited_idx
= MAX (ctx
->module
->max_inited_idx
, cfg
->method_index
);
2791 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2792 indexes
[1] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, FALSE
);
2793 inited_var
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, ctx
->module
->inited_var
, indexes
, 2, ""), "is_inited");
2795 args
[0] = inited_var
;
2796 args
[1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE
);
2797 inited_var
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i8"), args
, 2, "");
2799 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, inited_var
, LLVMConstInt (LLVMTypeOf (inited_var
), 0, FALSE
), "");
2801 inited_bb
= ctx
->inited_bb
;
2802 notinited_bb
= gen_bb (ctx
, "NOTINITED_BB");
2804 LLVMBuildCondBr (ctx
->builder
, cmp
, notinited_bb
, inited_bb
);
2806 builder
= ctx
->builder
= create_builder (ctx
);
2807 LLVMPositionBuilderAtEnd (ctx
->builder
, notinited_bb
);
2810 if (ctx
->rgctx_arg
&& cfg
->method
->is_inflated
&& mono_method_get_context (cfg
->method
)->method_inst
) {
2811 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2812 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2813 callee
= ctx
->module
->init_method_gshared_mrgctx
;
2814 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2815 } else if (ctx
->rgctx_arg
) {
2816 /* A vtable is passed as the rgctx argument */
2817 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2818 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2819 callee
= ctx
->module
->init_method_gshared_vtable
;
2820 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2821 } else if (cfg
->gshared
) {
2822 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2823 args
[1] = convert (ctx
, ctx
->this_arg
, ObjRefType ());
2824 callee
= ctx
->module
->init_method_gshared_this
;
2825 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2827 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2828 callee
= ctx
->module
->init_method
;
2829 call
= LLVMBuildCall (builder
, callee
, args
, 1, "");
2833 * This enables llvm to keep arguments in their original registers/
2834 * scratch registers, since the call will not clobber them.
2836 mono_llvm_set_call_preserveall_cc (call
);
2838 LLVMBuildBr (builder
, inited_bb
);
2839 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= inited_bb
;
2841 builder
= ctx
->builder
= create_builder (ctx
);
2842 LLVMPositionBuilderAtEnd (ctx
->builder
, inited_bb
);
2846 emit_unbox_tramp (EmitContext
*ctx
, const char *method_name
, LLVMTypeRef method_type
, LLVMValueRef method
, int method_index
)
2849 * Emit unbox trampoline using a tail call
2851 LLVMValueRef tramp
, call
, *args
;
2852 LLVMBuilderRef builder
;
2853 LLVMBasicBlockRef lbb
;
2854 LLVMCallInfo
*linfo
;
2858 tramp_name
= g_strdup_printf ("ut_%s", method_name
);
2859 tramp
= LLVMAddFunction (ctx
->module
->lmodule
, tramp_name
, method_type
);
2860 LLVMSetLinkage (tramp
, LLVMInternalLinkage
);
2861 LLVMAddFunctionAttr (tramp
, LLVMOptimizeForSizeAttribute
);
2862 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2864 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2865 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2866 LLVMAddAttribute (LLVMGetParam (tramp
, ctx
->rgctx_arg_pindex
), LLVMInRegAttribute
);
2867 if (ctx
->cfg
->vret_addr
) {
2868 LLVMSetValueName (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), "vret");
2869 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
2870 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
2871 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
2875 lbb
= LLVMAppendBasicBlock (tramp
, "");
2876 builder
= LLVMCreateBuilder ();
2877 LLVMPositionBuilderAtEnd (builder
, lbb
);
2879 nargs
= LLVMCountParamTypes (method_type
);
2880 args
= g_new0 (LLVMValueRef
, nargs
);
2881 for (i
= 0; i
< nargs
; ++i
) {
2882 args
[i
] = LLVMGetParam (tramp
, i
);
2883 if (i
== ctx
->this_arg_pindex
) {
2884 LLVMTypeRef arg_type
= LLVMTypeOf (args
[i
]);
2886 args
[i
] = LLVMBuildPtrToInt (builder
, args
[i
], IntPtrType (), "");
2887 args
[i
] = LLVMBuildAdd (builder
, args
[i
], LLVMConstInt (IntPtrType (), sizeof (MonoObject
), FALSE
), "");
2888 args
[i
] = LLVMBuildIntToPtr (builder
, args
[i
], arg_type
, "");
2891 call
= LLVMBuildCall (builder
, method
, args
, nargs
, "");
2892 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2893 LLVMAddInstrAttribute (call
, 1 + ctx
->rgctx_arg_pindex
, LLVMInRegAttribute
);
2894 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
)
2895 LLVMAddInstrAttribute (call
, 1 + linfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
2897 // FIXME: This causes assertions in clang
2898 //mono_llvm_set_must_tail (call);
2899 if (LLVMGetReturnType (method_type
) == LLVMVoidType ())
2900 LLVMBuildRetVoid (builder
);
2902 LLVMBuildRet (builder
, call
);
2904 g_hash_table_insert (ctx
->module
->idx_to_unbox_tramp
, GINT_TO_POINTER (method_index
), tramp
);
2905 LLVMDisposeBuilder (builder
);
2911 * Emit code to load/convert arguments.
2914 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
2917 MonoCompile
*cfg
= ctx
->cfg
;
2918 MonoMethodSignature
*sig
= ctx
->sig
;
2919 LLVMCallInfo
*linfo
= ctx
->linfo
;
2923 LLVMBuilderRef old_builder
= ctx
->builder
;
2924 ctx
->builder
= builder
;
2926 ctx
->alloca_builder
= create_builder (ctx
);
2929 * Handle indirect/volatile variables by allocating memory for them
2930 * using 'alloca', and storing their address in a temporary.
2932 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
2933 MonoInst
*var
= cfg
->varinfo
[i
];
2936 if (var
->opcode
== OP_GSHAREDVT_LOCAL
|| var
->opcode
== OP_GSHAREDVT_ARG_REGOFFSET
) {
2937 } else if (var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) || (mini_type_is_vtype (var
->inst_vtype
) && !MONO_CLASS_IS_SIMD (ctx
->cfg
, var
->klass
))) {
2938 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
2941 /* Could be already created by an OP_VPHI */
2942 if (!ctx
->addresses
[var
->dreg
]) {
2943 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
2944 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2946 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
2950 names
= g_new (char *, sig
->param_count
);
2951 mono_method_get_param_names (cfg
->method
, (const char **) names
);
2953 for (i
= 0; i
< sig
->param_count
; ++i
) {
2954 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
2955 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
2958 pindex
= ainfo
->pindex
;
2960 switch (ainfo
->storage
) {
2961 case LLVMArgVtypeInReg
:
2962 case LLVMArgAsFpArgs
: {
2963 LLVMValueRef args
[8];
2966 pindex
+= ainfo
->ndummy_fpargs
;
2968 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2969 memset (args
, 0, sizeof (args
));
2970 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2971 args
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
2972 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
2973 args
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
2975 g_assert (ainfo
->nslots
<= 8);
2976 for (j
= 0; j
< ainfo
->nslots
; ++j
)
2977 args
[j
] = LLVMGetParam (ctx
->lmethod
, pindex
+ j
);
2979 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
2981 emit_args_to_vtype (ctx
, builder
, ainfo
->type
, ctx
->addresses
[reg
], ainfo
, args
);
2983 if (ainfo
->storage
== LLVMArgVtypeInReg
&& MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2984 /* Treat these as normal values */
2985 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2989 case LLVMArgVtypeByVal
: {
2990 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
2992 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2993 /* Treat these as normal values */
2994 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2998 case LLVMArgVtypeByRef
: {
2999 /* The argument is passed by ref */
3000 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3003 case LLVMArgAsIArgs
: {
3004 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3007 /* The argument is received as an array of ints, store it into the real argument */
3008 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
3010 size
= mono_class_value_size (mono_class_from_mono_type (ainfo
->type
), NULL
);
3011 if (size
< SIZEOF_VOID_P
) {
3012 /* The upper bits of the registers might not be valid */
3013 LLVMValueRef val
= LLVMBuildExtractValue (builder
, arg
, 0, "");
3014 LLVMValueRef dest
= convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMIntType (size
* 8), 0));
3015 LLVMBuildStore (ctx
->builder
, LLVMBuildTrunc (builder
, val
, LLVMIntType (size
* 8), ""), dest
);
3017 LLVMBuildStore (ctx
->builder
, arg
, convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMTypeOf (arg
), 0)));
3021 case LLVMArgVtypeAsScalar
:
3022 g_assert_not_reached ();
3024 case LLVMArgGsharedvtFixed
: {
3025 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3026 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3029 name
= g_strdup_printf ("arg_%s", names
[i
]);
3031 name
= g_strdup_printf ("arg_%d", i
);
3033 ctx
->values
[reg
] = LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), name
);
3036 case LLVMArgGsharedvtFixedVtype
: {
3037 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
3040 name
= g_strdup_printf ("vtype_arg_%s", names
[i
]);
3042 name
= g_strdup_printf ("vtype_arg_%d", i
);
3044 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3045 g_assert (ctx
->addresses
[reg
]);
3046 LLVMSetValueName (ctx
->addresses
[reg
], name
);
3047 LLVMBuildStore (builder
, LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), ""), ctx
->addresses
[reg
]);
3050 case LLVMArgGsharedvtVariable
:
3051 /* The IR treats these as variables with addresses */
3052 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3055 ctx
->values
[reg
] = convert_full (ctx
, ctx
->values
[reg
], llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, ainfo
->type
)), type_is_unsigned (ctx
, ainfo
->type
));
3062 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
3064 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
3065 for (i
= 0; i
< sig
->param_count
; ++i
)
3066 if (!mini_type_is_vtype (sig
->params
[i
]))
3067 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
3069 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->gshared
) {
3070 LLVMValueRef this_alloc
;
3073 * The exception handling code needs the location where the this argument was
3074 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3075 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3076 * location into the LSDA.
3078 this_alloc
= mono_llvm_build_alloca (builder
, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
3079 /* This volatile store will keep the alloca alive */
3080 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3082 set_metadata_flag (this_alloc
, "mono.this");
3085 if (cfg
->rgctx_var
) {
3086 LLVMValueRef rgctx_alloc
, store
;
3089 * We handle the rgctx arg similarly to the this pointer.
3091 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
3092 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
3093 /* This volatile store will keep the alloca alive */
3094 store
= mono_llvm_build_store (builder
, convert (ctx
, ctx
->rgctx_arg
, IntPtrType ()), rgctx_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3096 set_metadata_flag (rgctx_alloc
, "mono.this");
3099 /* Initialize the method if needed */
3100 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
3101 /* Emit a location for the initialization code */
3102 ctx
->init_bb
= gen_bb (ctx
, "INIT_BB");
3103 ctx
->inited_bb
= gen_bb (ctx
, "INITED_BB");
3105 LLVMBuildBr (ctx
->builder
, ctx
->init_bb
);
3106 builder
= ctx
->builder
= create_builder (ctx
);
3107 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->inited_bb
);
3108 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= ctx
->inited_bb
;
3111 /* Compute nesting between clauses */
3112 ctx
->nested_in
= (GSList
**)mono_mempool_alloc0 (cfg
->mempool
, sizeof (GSList
*) * cfg
->header
->num_clauses
);
3113 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
3114 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
3115 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
3116 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
3118 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
)
3119 ctx
->nested_in
[i
] = g_slist_prepend_mempool (cfg
->mempool
, ctx
->nested_in
[i
], GINT_TO_POINTER (j
));
3124 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3125 * it needs to continue normally, or return back to the exception handling system.
3127 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3131 if (!(bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
)))
3134 clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3135 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
3136 g_hash_table_insert (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
), bb
);
3138 if (bb
->in_scount
== 0) {
3141 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
3142 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
3143 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
3145 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
3147 /* Create a variable to hold the exception var */
3149 ctx
->ex_var
= LLVMBuildAlloca (builder
, ObjRefType (), "exvar");
3153 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3154 * LLVM bblock containing a landing pad causes problems for the
3155 * LLVM optimizer passes.
3157 sprintf (name
, "BB%d_CALL_HANDLER_TARGET", bb
->block_num
);
3158 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
3160 ctx
->builder
= old_builder
;
3164 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
3166 MonoCompile
*cfg
= ctx
->cfg
;
3167 LLVMValueRef
*values
= ctx
->values
;
3168 LLVMValueRef
*addresses
= ctx
->addresses
;
3169 MonoCallInst
*call
= (MonoCallInst
*)ins
;
3170 MonoMethodSignature
*sig
= call
->signature
;
3171 LLVMValueRef callee
= NULL
, lcall
;
3173 LLVMCallInfo
*cinfo
;
3177 LLVMTypeRef llvm_sig
;
3179 gboolean is_virtual
, calli
, preserveall
;
3180 LLVMBuilderRef builder
= *builder_ref
;
3182 if ((call
->signature
->call_convention
!= MONO_CALL_DEFAULT
) && !((call
->signature
->call_convention
== MONO_CALL_C
) && ctx
->llvm_only
)) {
3183 set_failure (ctx
, "non-default callconv");
3187 cinfo
= call
->cinfo
;
3189 if (call
->rgctx_arg_reg
)
3190 cinfo
->rgctx_arg
= TRUE
;
3191 if (call
->imt_arg_reg
)
3192 cinfo
->imt_arg
= TRUE
;
3194 vretaddr
= (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| cinfo
->ret
.storage
== LLVMArgVtypeByRef
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| cinfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
3196 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
);
3200 is_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
|| ins
->opcode
== OP_RCALL_MEMBASE
);
3201 calli
= !call
->fptr_is_patch
&& (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
|| ins
->opcode
== OP_RCALL_REG
);
3203 preserveall
= FALSE
;
3205 /* FIXME: Avoid creating duplicate methods */
3207 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3211 if (cfg
->compile_aot
) {
3212 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
3214 set_failure (ctx
, "can't encode patch");
3217 if (cfg
->llvm_only
&& call
->method
->klass
->image
->assembly
== ctx
->module
->assembly
) {
3219 * Collect instructions representing the callee into a hash so they can be replaced
3220 * by the llvm method for the callee if the callee turns out to be direct
3221 * callable. Currently this only requires it to not fail llvm compilation.
3223 GSList
*l
= (GSList
*)g_hash_table_lookup (ctx
->method_to_callers
, call
->method
);
3224 l
= g_slist_prepend (l
, callee
);
3225 g_hash_table_insert (ctx
->method_to_callers
, call
->method
, l
);
3229 static int tramp_index
;
3232 name
= g_strdup_printf ("tramp_%d", tramp_index
);
3235 #if LLVM_API_VERSION > 100
3237 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3238 * Make all calls through a global. The address of the global will be saved in
3239 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3242 LLVMValueRef tramp_var
= g_hash_table_lookup (ctx
->jit_callees
, call
->method
);
3245 mono_create_jit_trampoline (mono_domain_get (),
3246 call
->method
, &error
);
3247 if (!is_ok (&error
)) {
3248 set_failure (ctx
, mono_error_get_message (&error
));
3249 mono_error_cleanup (&error
);
3253 tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
3254 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
3255 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
3256 g_hash_table_insert (ctx
->jit_callees
, call
->method
, tramp_var
);
3258 callee
= LLVMBuildLoad (builder
, tramp_var
, "");
3261 mono_create_jit_trampoline (mono_domain_get (),
3262 call
->method
, &error
);
3263 if (!is_ok (&error
)) {
3265 set_failure (ctx
, mono_error_get_message (&error
));
3266 mono_error_cleanup (&error
);
3270 callee
= LLVMAddFunction (ctx
->lmodule
, name
, llvm_sig
);
3273 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3278 if (!cfg
->llvm_only
&& call
->method
&& strstr (call
->method
->klass
->name
, "AsyncVoidMethodBuilder")) {
3279 /* LLVM miscompiles async methods */
3280 set_failure (ctx
, "#13734");
3285 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
3291 memset (&ji, 0, sizeof (ji));
3292 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3293 ji.data.target = info->name;
3295 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3297 if (cfg
->compile_aot
) {
3298 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
3300 set_failure (ctx
, "can't encode patch");
3304 target
= (gpointer
)mono_icall_get_wrapper (info
);
3305 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3308 if (cfg
->compile_aot
) {
3310 if (cfg
->abs_patches
) {
3311 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3313 callee
= get_callee (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3315 set_failure (ctx
, "can't encode patch");
3321 set_failure (ctx
, "aot");
3325 #if LLVM_API_VERSION > 100
3326 if (cfg
->abs_patches
) {
3327 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3331 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3332 mono_error_assert_ok (&error
);
3333 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3335 g_assert_not_reached ();
3338 g_assert_not_reached ();
3341 callee
= LLVMAddFunction (ctx
->lmodule
, "", llvm_sig
);
3343 if (cfg
->abs_patches
) {
3344 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3349 * FIXME: Some trampolines might have
3350 * their own calling convention on some platforms.
3352 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3353 mono_error_assert_ok (&error
);
3354 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3358 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, (gpointer
)call
->fptr
);
3365 int size
= sizeof (gpointer
);
3368 g_assert (ins
->inst_offset
% size
== 0);
3369 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3371 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
3373 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
3375 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3380 * Collect and convert arguments
3382 nargs
= (sig
->param_count
* 16) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
;
3383 len
= sizeof (LLVMValueRef
) * nargs
;
3384 args
= (LLVMValueRef
*)alloca (len
);
3385 memset (args
, 0, len
);
3386 l
= call
->out_ireg_args
;
3388 if (call
->rgctx_arg_reg
) {
3389 g_assert (values
[call
->rgctx_arg_reg
]);
3390 g_assert (cinfo
->rgctx_arg_pindex
< nargs
);
3392 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3393 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3394 * it using a volatile load.
3397 if (!ctx
->imt_rgctx_loc
)
3398 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3399 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3400 args
[cinfo
->rgctx_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3402 args
[cinfo
->rgctx_arg_pindex
] = convert (ctx
, values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
);
3405 if (call
->imt_arg_reg
) {
3406 g_assert (!ctx
->llvm_only
);
3407 g_assert (values
[call
->imt_arg_reg
]);
3408 g_assert (cinfo
->imt_arg_pindex
< nargs
);
3410 if (!ctx
->imt_rgctx_loc
)
3411 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3412 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3413 args
[cinfo
->imt_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3415 args
[cinfo
->imt_arg_pindex
] = convert (ctx
, values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
);
3418 switch (cinfo
->ret
.storage
) {
3419 case LLVMArgGsharedvtVariable
: {
3420 MonoInst
*var
= get_vreg_to_inst (cfg
, call
->inst
.dreg
);
3422 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
3423 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), IntPtrType ());
3425 g_assert (addresses
[call
->inst
.dreg
]);
3426 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3432 if (!addresses
[call
->inst
.dreg
])
3433 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3434 g_assert (cinfo
->vret_arg_pindex
< nargs
);
3435 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3436 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3438 args
[cinfo
->vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
3444 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3445 * use the real callee for argument type conversion.
3447 LLVMTypeRef callee_type
= LLVMGetElementType (LLVMTypeOf (callee
));
3448 LLVMTypeRef
*param_types
= (LLVMTypeRef
*)g_alloca (sizeof (LLVMTypeRef
) * LLVMCountParamTypes (callee_type
));
3449 LLVMGetParamTypes (callee_type
, param_types
);
3451 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
3454 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
];
3456 pindex
= ainfo
->pindex
;
3458 regpair
= (guint32
)(gssize
)(l
->data
);
3459 reg
= regpair
& 0xffffff;
3460 args
[pindex
] = values
[reg
];
3461 switch (ainfo
->storage
) {
3462 case LLVMArgVtypeInReg
:
3463 case LLVMArgAsFpArgs
: {
3467 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
3468 args
[pindex
+ j
] = LLVMConstNull (LLVMDoubleType ());
3469 pindex
+= ainfo
->ndummy_fpargs
;
3471 g_assert (addresses
[reg
]);
3472 emit_vtype_to_args (ctx
, builder
, ainfo
->type
, addresses
[reg
], ainfo
, args
+ pindex
, &nargs
);
3476 // FIXME: Get rid of the VMOVE
3479 case LLVMArgVtypeByVal
:
3480 g_assert (addresses
[reg
]);
3481 args
[pindex
] = addresses
[reg
];
3483 case LLVMArgVtypeByRef
: {
3484 g_assert (addresses
[reg
]);
3485 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3488 case LLVMArgAsIArgs
:
3489 g_assert (addresses
[reg
]);
3490 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo
->nslots
), 0)), "");
3492 case LLVMArgVtypeAsScalar
:
3493 g_assert_not_reached ();
3495 case LLVMArgGsharedvtFixed
:
3496 case LLVMArgGsharedvtFixedVtype
:
3497 g_assert (addresses
[reg
]);
3498 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3500 case LLVMArgGsharedvtVariable
:
3501 g_assert (addresses
[reg
]);
3502 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (IntPtrType (), 0));
3505 g_assert (args
[pindex
]);
3506 if (i
== 0 && sig
->hasthis
)
3507 args
[pindex
] = convert (ctx
, args
[pindex
], param_types
[pindex
]);
3509 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, ainfo
->type
));
3512 g_assert (pindex
<= nargs
);
3517 // FIXME: Align call sites
3523 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
3525 if (ins
->opcode
!= OP_TAILCALL
&& LLVMGetInstructionOpcode (lcall
) == LLVMCall
)
3526 mono_llvm_set_call_notail (lcall
);
3529 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3531 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3532 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
3534 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3535 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
3536 if (!sig
->pinvoke
&& !cfg
->llvm_only
)
3537 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
3539 mono_llvm_set_call_preserveall_cc (lcall
);
3541 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3542 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
3543 if (!ctx
->llvm_only
&& call
->rgctx_arg_reg
)
3544 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->rgctx_arg_pindex
, LLVMInRegAttribute
);
3545 if (call
->imt_arg_reg
)
3546 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->imt_arg_pindex
, LLVMInRegAttribute
);
3548 /* Add byval attributes if needed */
3549 for (i
= 0; i
< sig
->param_count
; ++i
) {
3550 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
+ sig
->hasthis
];
3552 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
)
3553 LLVMAddInstrAttribute (lcall
, 1 + ainfo
->pindex
, LLVMByValAttribute
);
3557 * Convert the result
3559 switch (cinfo
->ret
.storage
) {
3560 case LLVMArgVtypeInReg
: {
3561 LLVMValueRef regs
[2];
3563 if (LLVMTypeOf (lcall
) == LLVMVoidType ())
3567 if (!addresses
[ins
->dreg
])
3568 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
3570 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
3571 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
3572 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
3573 emit_args_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
3576 case LLVMArgVtypeByVal
:
3577 if (!addresses
[call
->inst
.dreg
])
3578 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3579 LLVMBuildStore (builder
, lcall
, addresses
[call
->inst
.dreg
]);
3581 case LLVMArgAsIArgs
:
3582 case LLVMArgFpStruct
:
3583 if (!addresses
[call
->inst
.dreg
])
3584 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3585 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3587 case LLVMArgVtypeAsScalar
:
3588 if (!addresses
[call
->inst
.dreg
])
3589 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3590 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3592 case LLVMArgVtypeRetAddr
:
3593 case LLVMArgVtypeByRef
:
3594 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
))) {
3595 /* Some opcodes like STOREX_MEMBASE access these by value */
3596 g_assert (addresses
[call
->inst
.dreg
]);
3597 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3600 case LLVMArgGsharedvtVariable
:
3602 case LLVMArgGsharedvtFixed
:
3603 case LLVMArgGsharedvtFixedVtype
:
3604 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3607 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
3608 /* If the method returns an unsigned value, need to zext it */
3609 values
[ins
->dreg
] = convert_full (ctx
, lcall
, llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, sig
->ret
)), type_is_unsigned (ctx
, sig
->ret
));
3613 *builder_ref
= ctx
->builder
;
3617 emit_llvmonly_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3619 const char *icall_name
= rethrow
? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3620 LLVMValueRef callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3622 LLVMTypeRef exc_type
= type_to_llvm_type (ctx
, &mono_get_exception_class ()->byval_arg
);
3625 LLVMTypeRef fun_sig
= LLVMFunctionType1 (LLVMVoidType (), exc_type
, FALSE
);
3627 if (ctx
->cfg
->compile_aot
) {
3628 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, icall_name
);
3630 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3631 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3632 mono_memory_barrier ();
3635 ctx
->module
->rethrow
= callee
;
3637 ctx
->module
->throw_icall
= callee
;
3641 LLVMValueRef args
[2];
3643 args
[0] = convert (ctx
, exc
, exc_type
);
3644 emit_call (ctx
, bb
, &ctx
->builder
, callee
, args
, 1);
3646 LLVMBuildUnreachable (ctx
->builder
);
3648 ctx
->builder
= create_builder (ctx
);
3652 emit_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3654 MonoMethodSignature
*throw_sig
;
3655 LLVMValueRef callee
, arg
;
3656 const char *icall_name
;
3658 callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3659 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3662 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
3663 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
3664 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
3665 if (ctx
->cfg
->compile_aot
) {
3666 callee
= get_callee (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3671 * LLVM doesn't push the exception argument, so we need a different
3674 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3676 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3678 callee
= emit_jit_callee (ctx
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
), target
);
3681 mono_memory_barrier ();
3682 #if LLVM_API_VERSION < 100
3684 ctx
->module
->rethrow
= callee
;
3686 ctx
->module
->throw_icall
= callee
;
3689 arg
= convert (ctx
, exc
, type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
3690 emit_call (ctx
, bb
, &ctx
->builder
, callee
, &arg
, 1);
3694 emit_resume_eh (EmitContext
*ctx
, MonoBasicBlock
*bb
)
3696 const char *icall_name
= "mono_llvm_resume_exception";
3697 LLVMValueRef callee
= ctx
->module
->resume_eh
;
3699 LLVMTypeRef fun_sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
3702 if (ctx
->cfg
->compile_aot
) {
3703 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3705 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3706 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3707 mono_memory_barrier ();
3709 ctx
->module
->resume_eh
= callee
;
3713 emit_call (ctx
, bb
, &ctx
->builder
, callee
, NULL
, 0);
3715 LLVMBuildUnreachable (ctx
->builder
);
3717 ctx
->builder
= create_builder (ctx
);
3721 mono_llvm_emit_clear_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3723 const char *icall_name
= "mono_llvm_clear_exception";
3725 LLVMTypeRef call_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
3726 LLVMValueRef callee
= NULL
;
3729 if (ctx
->cfg
->compile_aot
) {
3730 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3732 // FIXME: This is broken.
3733 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3737 g_assert (builder
&& callee
);
3739 return LLVMBuildCall (builder
, callee
, NULL
, 0, "");
3743 mono_llvm_emit_load_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3745 const char *icall_name
= "mono_llvm_load_exception";
3747 LLVMTypeRef call_sig
= LLVMFunctionType (ObjRefType (), NULL
, 0, FALSE
);
3748 LLVMValueRef callee
= NULL
;
3751 if (ctx
->cfg
->compile_aot
) {
3752 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3754 // FIXME: This is broken.
3755 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3759 g_assert (builder
&& callee
);
3761 return LLVMBuildCall (builder
, callee
, NULL
, 0, icall_name
);
3766 mono_llvm_emit_match_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
, gint32 region_start
, gint32 region_end
)
3768 const char *icall_name
= "mono_llvm_match_exception";
3770 ctx
->builder
= builder
;
3772 const int num_args
= 5;
3773 LLVMValueRef args
[num_args
];
3774 args
[0] = convert (ctx
, get_aotconst (ctx
, MONO_PATCH_INFO_AOT_JIT_INFO
, GINT_TO_POINTER (ctx
->cfg
->method_index
)), IntPtrType ());
3775 args
[1] = LLVMConstInt (LLVMInt32Type (), region_start
, 0);
3776 args
[2] = LLVMConstInt (LLVMInt32Type (), region_end
, 0);
3777 if (ctx
->cfg
->rgctx_var
) {
3778 LLVMValueRef rgctx_alloc
= ctx
->addresses
[ctx
->cfg
->rgctx_var
->dreg
];
3779 g_assert (rgctx_alloc
);
3780 args
[3] = LLVMBuildLoad (builder
, convert (ctx
, rgctx_alloc
, LLVMPointerType (IntPtrType (), 0)), "");
3782 args
[3] = LLVMConstInt (IntPtrType (), 0, 0);
3785 args
[4] = convert (ctx
, ctx
->this_arg
, IntPtrType ());
3787 args
[4] = LLVMConstInt (IntPtrType (), 0, 0);
3789 LLVMTypeRef match_sig
= LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE
);
3790 LLVMValueRef callee
= ctx
->module
->match_exc
;
3793 if (ctx
->cfg
->compile_aot
) {
3794 ctx
->builder
= builder
;
3795 // get_callee expects ctx->builder to be the emitting builder
3796 callee
= get_callee (ctx
, match_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3798 callee
= ctx
->module
->match_exc
= LLVMAddFunction (ctx
->lmodule
, icall_name
, match_sig
);
3799 LLVMAddGlobalMapping (ctx
->module
->ee
, ctx
->module
->match_exc
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3800 ctx
->module
->match_exc
= callee
;
3801 mono_memory_barrier ();
3805 g_assert (builder
&& callee
);
3807 g_assert (ctx
->ex_var
);
3809 return LLVMBuildCall (builder
, callee
, args
, num_args
, icall_name
);
3812 // FIXME: This won't work because the code-finding makes this
3814 /*#define MONO_PERSONALITY_DEBUG*/
3816 #ifdef MONO_PERSONALITY_DEBUG
3817 static const gboolean use_debug_personality
= TRUE
;
3818 static const char *default_personality_name
= "mono_debug_personality";
3820 static const gboolean use_debug_personality
= FALSE
;
3821 static const char *default_personality_name
= "__gxx_personality_v0";
3825 default_cpp_lpad_exc_signature (void)
3827 static gboolean inited
= FALSE
;
3828 static LLVMTypeRef sig
;
3831 LLVMTypeRef signature
[2];
3832 signature
[0] = LLVMPointerType (LLVMInt8Type (), 0);
3833 signature
[1] = LLVMInt32Type ();
3834 sig
= LLVMStructType (signature
, 2, FALSE
);
3842 get_mono_personality (EmitContext
*ctx
)
3844 LLVMValueRef personality
= NULL
;
3845 static gint32 mapping_inited
= FALSE
;
3846 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
3848 if (!use_debug_personality
) {
3849 if (ctx
->cfg
->compile_aot
) {
3850 personality
= get_intrinsic (ctx
, default_personality_name
);
3851 } else if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0) {
3852 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3853 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, personality
);
3856 if (ctx
->cfg
->compile_aot
) {
3857 personality
= get_callee (ctx
, personality_type
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
);
3859 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3860 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
));
3861 mono_memory_barrier ();
3865 g_assert (personality
);
3869 static LLVMBasicBlockRef
3870 emit_landing_pad (EmitContext
*ctx
, int group_index
, int group_size
)
3872 MonoCompile
*cfg
= ctx
->cfg
;
3873 LLVMBuilderRef old_builder
= ctx
->builder
;
3874 MonoExceptionClause
*group_start
= cfg
->header
->clauses
+ group_index
;
3876 LLVMBuilderRef lpadBuilder
= create_builder (ctx
);
3877 ctx
->builder
= lpadBuilder
;
3879 MonoBasicBlock
*handler_bb
= cfg
->cil_offset_to_bb
[CLAUSE_START (group_start
)];
3880 g_assert (handler_bb
);
3882 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3883 LLVMValueRef personality
= get_mono_personality (ctx
);
3884 g_assert (personality
);
3886 char *bb_name
= g_strdup_printf ("LPAD%d_BB", group_index
);
3887 LLVMBasicBlockRef lpad_bb
= gen_bb (ctx
, bb_name
);
3889 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3890 LLVMValueRef landing_pad
= LLVMBuildLandingPad (lpadBuilder
, default_cpp_lpad_exc_signature (), personality
, 0, "");
3891 g_assert (landing_pad
);
3893 LLVMValueRef cast
= LLVMBuildBitCast (lpadBuilder
, ctx
->module
->sentinel_exception
, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3894 LLVMAddClause (landing_pad
, cast
);
3896 LLVMBasicBlockRef resume_bb
= gen_bb (ctx
, "RESUME_BB");
3897 LLVMBuilderRef resume_builder
= create_builder (ctx
);
3898 ctx
->builder
= resume_builder
;
3899 LLVMPositionBuilderAtEnd (resume_builder
, resume_bb
);
3901 emit_resume_eh (ctx
, handler_bb
);
3904 ctx
->builder
= lpadBuilder
;
3905 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3907 gboolean finally_only
= TRUE
;
3909 MonoExceptionClause
*group_cursor
= group_start
;
3911 for (int i
= 0; i
< group_size
; i
++) {
3912 if (!(group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
))
3913 finally_only
= FALSE
;
3919 // Handle landing pad inlining
3921 if (!finally_only
) {
3922 // So at each level of the exception stack we will match the exception again.
3923 // During that match, we need to compare against the handler types for the current
3924 // protected region. We send the try start and end so that we can only check against
3925 // handlers for this lexical protected region.
3926 LLVMValueRef match
= mono_llvm_emit_match_exception_call (ctx
, lpadBuilder
, group_start
->try_offset
, group_start
->try_offset
+ group_start
->try_len
);
3928 // if returns -1, resume
3929 LLVMValueRef switch_ins
= LLVMBuildSwitch (lpadBuilder
, match
, resume_bb
, group_size
);
3931 // else move to that target bb
3932 for (int i
= 0; i
< group_size
; i
++) {
3933 MonoExceptionClause
*clause
= group_start
+ i
;
3934 int clause_index
= clause
- cfg
->header
->clauses
;
3935 MonoBasicBlock
*handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3936 g_assert (handler_bb
);
3937 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3938 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3941 int clause_index
= group_start
- cfg
->header
->clauses
;
3942 MonoBasicBlock
*finally_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3943 g_assert (finally_bb
);
3945 LLVMBuildBr (ctx
->builder
, ctx
->bblocks
[finally_bb
->block_num
].call_handler_target_bb
);
3948 ctx
->builder
= old_builder
;
3955 emit_llvmonly_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBasicBlockRef cbb
)
3957 int clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3958 MonoExceptionClause
*clause
= &ctx
->cfg
->header
->clauses
[clause_index
];
3960 // Make exception available to catch blocks
3961 if (!(clause
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
)) {
3962 LLVMValueRef mono_exc
= mono_llvm_emit_load_exception_call (ctx
, ctx
->builder
);
3964 g_assert (ctx
->ex_var
);
3965 LLVMBuildStore (ctx
->builder
, LLVMBuildBitCast (ctx
->builder
, mono_exc
, ObjRefType (), ""), ctx
->ex_var
);
3967 if (bb
->in_scount
== 1) {
3968 MonoInst
*exvar
= bb
->in_stack
[0];
3969 g_assert (!ctx
->values
[exvar
->dreg
]);
3970 g_assert (ctx
->ex_var
);
3971 ctx
->values
[exvar
->dreg
] = LLVMBuildLoad (ctx
->builder
, ctx
->ex_var
, "save_exception");
3972 emit_volatile_store (ctx
, exvar
->dreg
);
3975 mono_llvm_emit_clear_exception_call (ctx
, ctx
->builder
);
3978 LLVMBuilderRef handler_builder
= create_builder (ctx
);
3979 LLVMBasicBlockRef target_bb
= ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
;
3980 LLVMPositionBuilderAtEnd (handler_builder
, target_bb
);
3982 // Make the handler code end with a jump to cbb
3983 LLVMBuildBr (handler_builder
, cbb
);
3987 emit_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef builder
)
3989 MonoCompile
*cfg
= ctx
->cfg
;
3990 LLVMValueRef
*values
= ctx
->values
;
3991 LLVMModuleRef lmodule
= ctx
->lmodule
;
3992 BBInfo
*bblocks
= ctx
->bblocks
;
3994 LLVMValueRef personality
;
3995 LLVMValueRef landing_pad
;
3996 LLVMBasicBlockRef target_bb
;
3998 static int ti_generator
;
4000 LLVMValueRef type_info
;
4004 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4006 if (cfg
->compile_aot
) {
4007 /* Use a dummy personality function */
4008 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
4009 g_assert (personality
);
4011 #if LLVM_API_VERSION > 100
4012 personality
= ctx
->module
->personality
;
4014 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
4015 personality
= LLVMAddFunction (ctx
->lmodule
, "mono_personality", personality_type
);
4016 LLVMAddFunctionAttr (personality
, LLVMNoUnwindAttribute
);
4017 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (personality
, "ENTRY");
4018 LLVMBuilderRef builder2
= LLVMCreateBuilder ();
4019 LLVMPositionBuilderAtEnd (builder2
, entry_bb
);
4020 LLVMBuildRet (builder2
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
));
4021 ctx
->module
->personality
= personality
;
4022 LLVMDisposeBuilder (builder2
);
4025 static gint32 mapping_inited
;
4027 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
4029 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
4030 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, (gpointer
)mono_personality
);
4034 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
4036 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
4039 * Create the type info
4041 sprintf (ti_name
, "type_info_%d", ti_generator
);
4044 if (cfg
->compile_aot
) {
4045 /* decode_eh_frame () in aot-runtime.c will decode this */
4046 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4047 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4050 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4052 LLVMSetLinkage (type_info
, LLVMInternalLinkage
);
4054 #if LLVM_API_VERSION > 100
4055 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4056 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4061 * After the cfg mempool is freed, the type info will point to stale memory,
4062 * but this is not a problem, since we decode it once in exception_cb during
4065 ti
= (gint32
*)mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
4066 *(gint32
*)ti
= clause_index
;
4068 type_info
= LLVMAddGlobal (lmodule
, i8ptr
, ti_name
);
4070 LLVMAddGlobalMapping (ctx
->module
->ee
, type_info
, ti
);
4075 LLVMTypeRef members
[2], ret_type
;
4077 members
[0] = i8ptr
;
4078 members
[1] = LLVMInt32Type ();
4079 ret_type
= LLVMStructType (members
, 2, FALSE
);
4081 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
4082 LLVMAddClause (landing_pad
, type_info
);
4084 /* Store the exception into the exvar */
4086 LLVMBuildStore (builder
, convert (ctx
, LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj"), ObjRefType ()), ctx
->ex_var
);
4090 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4091 * code expects control to be transferred to this landing pad even in the
4092 * presence of nested clauses. The landing pad needs to branch to the landing
4093 * pads belonging to nested clauses based on the selector value returned by
4094 * the landing pad instruction, which is passed to the landing pad in a
4095 * register by the EH code.
4097 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4098 g_assert (target_bb
);
4101 * Branch to the correct landing pad
4103 LLVMValueRef ex_selector
= LLVMBuildExtractValue (builder
, landing_pad
, 1, "ex_selector");
4104 LLVMValueRef switch_ins
= LLVMBuildSwitch (builder
, ex_selector
, target_bb
, 0);
4106 for (l
= ctx
->nested_in
[clause_index
]; l
; l
= l
->next
) {
4107 int nesting_clause_index
= GPOINTER_TO_INT (l
->data
);
4108 MonoBasicBlock
*handler_bb
;
4110 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (nesting_clause_index
));
4111 g_assert (handler_bb
);
4113 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4114 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), nesting_clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4117 /* Start a new bblock which CALL_HANDLER can branch to */
4118 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4120 ctx
->builder
= builder
= create_builder (ctx
);
4121 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
4123 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
4125 /* Store the exception into the IL level exvar */
4126 if (bb
->in_scount
== 1) {
4127 g_assert (bb
->in_scount
== 1);
4128 exvar
= bb
->in_stack
[0];
4130 // FIXME: This is shared with filter clauses ?
4131 g_assert (!values
[exvar
->dreg
]);
4133 g_assert (ctx
->ex_var
);
4134 values
[exvar
->dreg
] = LLVMBuildLoad (builder
, ctx
->ex_var
, "");
4135 emit_volatile_store (ctx
, exvar
->dreg
);
4141 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4143 MonoCompile
*cfg
= ctx
->cfg
;
4144 MonoMethodSignature
*sig
= ctx
->sig
;
4145 LLVMValueRef method
= ctx
->lmethod
;
4146 LLVMValueRef
*values
= ctx
->values
;
4147 LLVMValueRef
*addresses
= ctx
->addresses
;
4148 LLVMCallInfo
*linfo
= ctx
->linfo
;
4149 BBInfo
*bblocks
= ctx
->bblocks
;
4151 LLVMBasicBlockRef cbb
;
4152 LLVMBuilderRef builder
, starting_builder
;
4153 gboolean has_terminator
;
4155 LLVMValueRef lhs
, rhs
;
4158 cbb
= get_end_bb (ctx
, bb
);
4160 builder
= create_builder (ctx
);
4161 ctx
->builder
= builder
;
4162 LLVMPositionBuilderAtEnd (builder
, cbb
);
4167 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
4168 if (!ctx
->llvm_only
&& !bblocks
[bb
->block_num
].invoke_target
) {
4169 set_failure (ctx
, "handler without invokes");
4174 emit_llvmonly_handler_start (ctx
, bb
, cbb
);
4176 emit_handler_start (ctx
, bb
, builder
);
4179 builder
= ctx
->builder
;
4182 has_terminator
= FALSE
;
4183 starting_builder
= builder
;
4184 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4185 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
4187 char dname_buf
[128];
4189 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4194 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4195 * Start a new bblock.
4196 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4197 * from localloc-ed memory.
4199 if (!cfg
->llvm_only
)
4200 ;//set_failure (ctx, "basic block too long");
4202 if (!ctx
->long_bb_break_var
) {
4203 ctx
->long_bb_break_var
= build_alloca_llvm_type_name (ctx
, LLVMInt32Type (), 0, "long_bb_break");
4204 mono_llvm_build_store (ctx
->alloca_builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4207 cbb
= gen_bb (ctx
, "CONT_LONG_BB");
4208 LLVMBasicBlockRef dummy_bb
= gen_bb (ctx
, "CONT_LONG_BB_DUMMY");
4210 LLVMValueRef load
= mono_llvm_build_load (builder
, ctx
->long_bb_break_var
, "", TRUE
);
4212 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4213 * but llvm doesn't know that, so the branch is not going to be eliminated.
4215 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, load
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
4217 LLVMBuildCondBr (builder
, cmp
, cbb
, dummy_bb
);
4219 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4220 ctx
->builder
= builder
= create_builder (ctx
);
4221 LLVMPositionBuilderAtEnd (builder
, dummy_bb
);
4222 mono_llvm_build_store (builder
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), ctx
->long_bb_break_var
, TRUE
, LLVM_BARRIER_NONE
);
4223 LLVMBuildBr (builder
, cbb
);
4225 ctx
->builder
= builder
= create_builder (ctx
);
4226 LLVMPositionBuilderAtEnd (builder
, cbb
);
4227 ctx
->bblocks
[bb
->block_num
].end_bblock
= cbb
;
4232 /* There could be instructions after a terminator, skip them */
4235 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
4236 sprintf (dname_buf
, "t%d", ins
->dreg
);
4240 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
4241 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
4243 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) && var
->opcode
!= OP_GSHAREDVT_ARG_REGOFFSET
) {
4244 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
4246 /* It is ok for SETRET to have an uninitialized argument */
4247 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
) {
4248 set_failure (ctx
, "sreg1");
4251 lhs
= values
[ins
->sreg1
];
4257 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
4258 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
4259 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
4260 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
4262 if (!values
[ins
->sreg2
]) {
4263 set_failure (ctx
, "sreg2");
4266 rhs
= values
[ins
->sreg2
];
4272 //mono_print_ins (ins);
4273 switch (ins
->opcode
) {
4276 case OP_LIVERANGE_START
:
4277 case OP_LIVERANGE_END
:
4280 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
4283 #if SIZEOF_VOID_P == 4
4284 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4286 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
4290 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
4294 values
[ins
->dreg
] = LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
);
4296 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
4298 case OP_DUMMY_ICONST
:
4299 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4301 case OP_DUMMY_I8CONST
:
4302 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
4304 case OP_DUMMY_R8CONST
:
4305 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), 0.0f
);
4308 LLVMBasicBlockRef target_bb
= get_bb (ctx
, ins
->inst_target_bb
);
4309 LLVMBuildBr (builder
, target_bb
);
4310 has_terminator
= TRUE
;
4317 LLVMBasicBlockRef new_bb
;
4318 LLVMBuilderRef new_builder
;
4320 // The default branch is already handled
4321 // FIXME: Handle it here
4323 /* Start new bblock */
4324 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
4325 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
4327 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4328 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
4329 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
4330 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
4332 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
4335 new_builder
= create_builder (ctx
);
4336 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
4337 LLVMBuildUnreachable (new_builder
);
4339 has_terminator
= TRUE
;
4340 g_assert (!ins
->next
);
4346 switch (linfo
->ret
.storage
) {
4347 case LLVMArgVtypeInReg
: {
4348 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4349 LLVMValueRef val
, addr
, retval
;
4352 retval
= LLVMGetUndef (ret_type
);
4354 if (!addresses
[ins
->sreg1
]) {
4356 * The return type is an LLVM vector type, have to convert between it and the
4357 * real return type which is a struct type.
4359 g_assert (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
)));
4360 /* Convert to 2xi64 first */
4361 val
= LLVMBuildBitCast (builder
, values
[ins
->sreg1
], LLVMVectorType (IntPtrType (), 2), "");
4363 for (i
= 0; i
< 2; ++i
) {
4364 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4365 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildExtractElement (builder
, val
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), ""), i
, "");
4367 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4371 addr
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), "");
4372 for (i
= 0; i
< 2; ++i
) {
4373 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4374 LLVMValueRef indexes
[2], part_addr
;
4376 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4377 indexes
[1] = LLVMConstInt (LLVMInt32Type (), i
, FALSE
);
4378 part_addr
= LLVMBuildGEP (builder
, addr
, indexes
, 2, "");
4380 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildLoad (builder
, part_addr
, ""), i
, "");
4382 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4386 LLVMBuildRet (builder
, retval
);
4389 case LLVMArgVtypeAsScalar
: {
4390 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4391 LLVMValueRef retval
;
4393 g_assert (addresses
[ins
->sreg1
]);
4395 retval
= LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), ""), "");
4396 LLVMBuildRet (builder
, retval
);
4399 case LLVMArgVtypeByVal
: {
4400 LLVMValueRef retval
;
4402 g_assert (addresses
[ins
->sreg1
]);
4403 retval
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
4404 LLVMBuildRet (builder
, retval
);
4407 case LLVMArgVtypeByRef
: {
4408 LLVMBuildRetVoid (builder
);
4411 case LLVMArgGsharedvtFixed
: {
4412 LLVMTypeRef ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
4413 /* The return value is in lhs, need to store to the vret argument */
4414 /* sreg1 might not be set */
4416 g_assert (cfg
->vret_addr
);
4417 g_assert (values
[cfg
->vret_addr
->dreg
]);
4418 LLVMBuildStore (builder
, convert (ctx
, lhs
, ret_type
), convert (ctx
, values
[cfg
->vret_addr
->dreg
], LLVMPointerType (ret_type
, 0)));
4420 LLVMBuildRetVoid (builder
);
4423 case LLVMArgGsharedvtFixedVtype
: {
4425 LLVMBuildRetVoid (builder
);
4428 case LLVMArgGsharedvtVariable
: {
4430 LLVMBuildRetVoid (builder
);
4433 case LLVMArgVtypeRetAddr
: {
4434 LLVMBuildRetVoid (builder
);
4437 case LLVMArgAsIArgs
:
4438 case LLVMArgFpStruct
: {
4439 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4440 LLVMValueRef retval
;
4442 g_assert (addresses
[ins
->sreg1
]);
4443 retval
= LLVMBuildLoad (builder
, convert (ctx
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0)), "");
4444 LLVMBuildRet (builder
, retval
);
4448 case LLVMArgNormal
: {
4449 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
4451 * The method did not set its return value, probably because it
4452 * ends with a throw.
4455 LLVMBuildRetVoid (builder
);
4457 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
4459 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
4461 has_terminator
= TRUE
;
4465 g_assert_not_reached ();
4474 case OP_ICOMPARE_IMM
:
4475 case OP_LCOMPARE_IMM
:
4476 case OP_COMPARE_IMM
: {
4478 LLVMValueRef cmp
, args
[16];
4479 gboolean likely
= (ins
->flags
& MONO_INST_LIKELY
) != 0;
4481 if (ins
->next
->opcode
== OP_NOP
)
4484 if (ins
->next
->opcode
== OP_BR
)
4485 /* The comparison result is not needed */
4488 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
4490 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
4491 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4492 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4494 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4495 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4496 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4498 if (ins
->opcode
== OP_LCOMPARE
) {
4499 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4500 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
4502 if (ins
->opcode
== OP_ICOMPARE
) {
4503 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4504 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
4508 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4509 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
4510 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
4511 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
4514 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4515 if (ins
->opcode
== OP_FCOMPARE
) {
4516 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4517 } else if (ins
->opcode
== OP_RCOMPARE
) {
4518 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4519 } else if (ins
->opcode
== OP_COMPARE_IMM
) {
4520 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& ins
->inst_imm
== 0)
4521 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), "");
4523 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
4524 } else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4525 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
4526 /* The immediate is encoded in two fields */
4527 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
4528 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
4530 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
4533 else if (ins
->opcode
== OP_COMPARE
) {
4534 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
))
4535 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4537 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
4539 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4543 args
[1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
4544 cmp
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i1"), args
, 2, "");
4547 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
4548 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
4550 * If the target bb contains PHI instructions, LLVM requires
4551 * two PHI entries for this bblock, while we only generate one.
4552 * So convert this to an unconditional bblock. (bxc #171).
4554 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
4556 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
4558 has_terminator
= TRUE
;
4559 } else if (MONO_IS_SETCC (ins
->next
)) {
4560 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
4562 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4564 /* Add stores for volatile variables */
4565 emit_volatile_store (ctx
, ins
->next
->dreg
);
4566 } else if (MONO_IS_COND_EXC (ins
->next
)) {
4567 emit_cond_system_exception (ctx
, bb
, (const char*)ins
->next
->inst_p1
, cmp
);
4570 builder
= ctx
->builder
;
4572 set_failure (ctx
, "next");
4590 rel
= mono_opcode_to_cond (ins
->opcode
);
4592 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4593 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4604 rel
= mono_opcode_to_cond (ins
->opcode
);
4606 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4607 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4615 gboolean empty
= TRUE
;
4617 /* Check that all input bblocks really branch to us */
4618 for (i
= 0; i
< bb
->in_count
; ++i
) {
4619 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
4620 ins
->inst_phi_args
[i
+ 1] = -1;
4626 /* LLVM doesn't like phi instructions with zero operands */
4627 ctx
->is_dead
[ins
->dreg
] = TRUE
;
4631 /* Created earlier, insert it now */
4632 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
4634 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4635 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4639 * Count the number of times the incoming bblock branches to us,
4640 * since llvm requires a separate entry for each.
4642 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
4643 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
4646 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
4647 if (switch_ins
->inst_many_bb
[j
] == bb
)
4654 /* Remember for later */
4655 for (j
= 0; j
< count
; ++j
) {
4656 PhiNode
*node
= (PhiNode
*)mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
4659 node
->in_bb
= bb
->in_bb
[i
];
4661 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
);
4671 values
[ins
->dreg
] = lhs
;
4675 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
4678 values
[ins
->dreg
] = lhs
;
4680 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
4682 * This is added by the spilling pass in case of the JIT,
4683 * but we have to do it ourselves.
4685 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
4689 case OP_MOVE_F_TO_I4
: {
4690 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), ""), LLVMInt32Type (), "");
4693 case OP_MOVE_I4_TO_F
: {
4694 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType (), "");
4697 case OP_MOVE_F_TO_I8
: {
4698 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMInt64Type (), "");
4701 case OP_MOVE_I8_TO_F
: {
4702 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMDoubleType (), "");
4735 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4736 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4738 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, rhs
);
4741 builder
= ctx
->builder
;
4743 switch (ins
->opcode
) {
4746 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
4750 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
4754 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
4758 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
4762 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
4766 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
4770 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
4774 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4778 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
4782 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
4786 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
4790 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
4794 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
4798 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
4802 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4805 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4808 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4812 g_assert_not_reached ();
4819 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4820 rhs
= convert (ctx
, rhs
, LLVMFloatType ());
4821 switch (ins
->opcode
) {
4823 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4826 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4829 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4832 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4835 g_assert_not_reached ();
4844 case OP_IREM_UN_IMM
:
4846 case OP_IDIV_UN_IMM
:
4852 case OP_ISHR_UN_IMM
:
4862 case OP_LSHR_UN_IMM
:
4868 case OP_SHR_UN_IMM
: {
4871 if (spec
[MONO_INST_SRC1
] == 'l') {
4872 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4874 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4877 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, imm
);
4880 builder
= ctx
->builder
;
4882 #if SIZEOF_VOID_P == 4
4883 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
4884 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4887 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4888 lhs
= convert (ctx
, lhs
, IntPtrType ());
4889 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
4890 switch (ins
->opcode
) {
4894 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
4898 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
4903 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
4907 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
4909 case OP_IDIV_UN_IMM
:
4910 case OP_LDIV_UN_IMM
:
4911 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
4915 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
4917 case OP_IREM_UN_IMM
:
4918 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
4923 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
4927 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
4931 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
4936 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
4941 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
4943 case OP_ISHR_UN_IMM
:
4944 /* This is used to implement conv.u4, so the lhs could be an i8 */
4945 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4946 imm
= convert (ctx
, imm
, LLVMInt32Type ());
4947 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4949 case OP_LSHR_UN_IMM
:
4951 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4954 g_assert_not_reached ();
4959 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4962 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
4965 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
4966 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
4969 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4970 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMFloatType (), 0.0), lhs
, dname
);
4973 guint32 v
= 0xffffffff;
4974 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4978 guint64 v
= 0xffffffffffffffffLL
;
4979 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
4982 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4984 LLVMValueRef v1
, v2
;
4986 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
4987 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
4988 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
4993 case OP_ICONV_TO_I1
:
4994 case OP_ICONV_TO_I2
:
4995 case OP_ICONV_TO_I4
:
4996 case OP_ICONV_TO_U1
:
4997 case OP_ICONV_TO_U2
:
4998 case OP_ICONV_TO_U4
:
4999 case OP_LCONV_TO_I1
:
5000 case OP_LCONV_TO_I2
:
5001 case OP_LCONV_TO_U1
:
5002 case OP_LCONV_TO_U2
:
5003 case OP_LCONV_TO_U4
: {
5006 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
);
5008 /* Have to do two casts since our vregs have type int */
5009 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
5011 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
5013 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
5016 case OP_ICONV_TO_I8
:
5017 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
5019 case OP_ICONV_TO_U8
:
5020 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
5022 case OP_FCONV_TO_I4
:
5023 case OP_RCONV_TO_I4
:
5024 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
5026 case OP_FCONV_TO_I1
:
5027 case OP_RCONV_TO_I1
:
5028 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
5030 case OP_FCONV_TO_U1
:
5031 case OP_RCONV_TO_U1
:
5032 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildTrunc (builder
, LLVMBuildFPToUI (builder
, lhs
, IntPtrType (), dname
), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5034 case OP_FCONV_TO_I2
:
5035 case OP_RCONV_TO_I2
:
5036 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5038 case OP_FCONV_TO_U2
:
5039 case OP_RCONV_TO_U2
:
5040 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
5042 case OP_RCONV_TO_U4
:
5043 values
[ins
->dreg
] = LLVMBuildFPToUI (builder
, lhs
, LLVMInt32Type (), dname
);
5045 case OP_FCONV_TO_I8
:
5046 case OP_RCONV_TO_I8
:
5047 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
5050 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
5052 case OP_ICONV_TO_R8
:
5053 case OP_LCONV_TO_R8
:
5054 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5056 case OP_ICONV_TO_R_UN
:
5057 case OP_LCONV_TO_R_UN
:
5058 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
5060 #if SIZEOF_VOID_P == 4
5063 case OP_LCONV_TO_I4
:
5064 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5066 case OP_ICONV_TO_R4
:
5067 case OP_LCONV_TO_R4
:
5068 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
5070 values
[ins
->dreg
] = v
;
5072 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5074 case OP_FCONV_TO_R4
:
5075 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
5077 values
[ins
->dreg
] = v
;
5079 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5081 case OP_RCONV_TO_R8
:
5082 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, lhs
, LLVMDoubleType (), dname
);
5084 case OP_RCONV_TO_R4
:
5085 values
[ins
->dreg
] = lhs
;
5088 values
[ins
->dreg
] = LLVMBuildSExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5091 values
[ins
->dreg
] = LLVMBuildZExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5094 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5096 case OP_LOCALLOC_IMM
: {
5099 guint32 size
= ins
->inst_imm
;
5100 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
5102 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
5104 if (ins
->flags
& MONO_INST_INIT
) {
5105 LLVMValueRef args
[5];
5108 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5109 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
5110 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5111 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5112 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5115 values
[ins
->dreg
] = v
;
5119 LLVMValueRef v
, size
;
5121 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
), "");
5123 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
5125 if (ins
->flags
& MONO_INST_INIT
) {
5126 LLVMValueRef args
[5];
5129 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5131 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5132 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5133 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5135 values
[ins
->dreg
] = v
;
5139 case OP_LOADI1_MEMBASE
:
5140 case OP_LOADU1_MEMBASE
:
5141 case OP_LOADI2_MEMBASE
:
5142 case OP_LOADU2_MEMBASE
:
5143 case OP_LOADI4_MEMBASE
:
5144 case OP_LOADU4_MEMBASE
:
5145 case OP_LOADI8_MEMBASE
:
5146 case OP_LOADR4_MEMBASE
:
5147 case OP_LOADR8_MEMBASE
:
5148 case OP_LOAD_MEMBASE
:
5156 LLVMValueRef base
, index
, addr
;
5158 gboolean sext
= FALSE
, zext
= FALSE
;
5159 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5161 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5166 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
)) {
5167 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
5173 if (ins
->inst_offset
== 0) {
5175 } else if (ins
->inst_offset
% size
!= 0) {
5176 /* Unaligned load */
5177 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5178 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5180 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5181 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5185 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5187 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, base
, dname
, is_volatile
, LLVM_BARRIER_NONE
);
5189 if (!is_volatile
&& (ins
->flags
& MONO_INST_INVARIANT_LOAD
)) {
5191 * These will signal LLVM that these loads do not alias any stores, and
5192 * they can't fail, allowing them to be hoisted out of loops.
5194 set_invariant_load_flag (values
[ins
->dreg
]);
5195 #if LLVM_API_VERSION < 100
5196 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
5201 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5203 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5204 else if (!cfg
->r4fp
&& ins
->opcode
== OP_LOADR4_MEMBASE
)
5205 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
5209 case OP_STOREI1_MEMBASE_REG
:
5210 case OP_STOREI2_MEMBASE_REG
:
5211 case OP_STOREI4_MEMBASE_REG
:
5212 case OP_STOREI8_MEMBASE_REG
:
5213 case OP_STORER4_MEMBASE_REG
:
5214 case OP_STORER8_MEMBASE_REG
:
5215 case OP_STORE_MEMBASE_REG
: {
5217 LLVMValueRef index
, addr
, base
;
5219 gboolean sext
= FALSE
, zext
= FALSE
;
5220 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5222 if (!values
[ins
->inst_destbasereg
]) {
5223 set_failure (ctx
, "inst_destbasereg");
5227 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5229 base
= values
[ins
->inst_destbasereg
];
5230 if (ins
->inst_offset
% size
!= 0) {
5231 /* Unaligned store */
5232 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5233 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5235 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5236 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5238 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5242 case OP_STOREI1_MEMBASE_IMM
:
5243 case OP_STOREI2_MEMBASE_IMM
:
5244 case OP_STOREI4_MEMBASE_IMM
:
5245 case OP_STOREI8_MEMBASE_IMM
:
5246 case OP_STORE_MEMBASE_IMM
: {
5248 LLVMValueRef index
, addr
, base
;
5250 gboolean sext
= FALSE
, zext
= FALSE
;
5251 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5253 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5255 base
= values
[ins
->inst_destbasereg
];
5256 if (ins
->inst_offset
% size
!= 0) {
5257 /* Unaligned store */
5258 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5259 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5261 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5262 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5264 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5269 emit_load_general (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), lhs
, "", TRUE
, LLVM_BARRIER_NONE
);
5271 case OP_OUTARG_VTRETADDR
:
5279 case OP_VOIDCALL_MEMBASE
:
5280 case OP_CALL_MEMBASE
:
5281 case OP_LCALL_MEMBASE
:
5282 case OP_FCALL_MEMBASE
:
5283 case OP_RCALL_MEMBASE
:
5284 case OP_VCALL_MEMBASE
:
5285 case OP_VOIDCALL_REG
:
5290 case OP_VCALL_REG
: {
5291 process_call (ctx
, bb
, &builder
, ins
);
5296 LLVMValueRef indexes
[2];
5297 MonoJumpInfo
*tmp_ji
, *ji
;
5298 LLVMValueRef got_entry_addr
;
5302 * FIXME: Can't allocate from the cfg mempool since that is freed if
5303 * the LLVM compile fails.
5305 tmp_ji
= g_new0 (MonoJumpInfo
, 1);
5306 tmp_ji
->type
= (MonoJumpInfoType
)ins
->inst_c1
;
5307 tmp_ji
->data
.target
= ins
->inst_p0
;
5309 ji
= mono_aot_patch_info_dup (tmp_ji
);
5312 if (ji
->type
== MONO_PATCH_INFO_ICALL_ADDR
) {
5313 char *symbol
= mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL
, ji
->data
.target
);
5316 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5317 * resolvable at runtime using dlsym ().
5320 values
[ins
->dreg
] = LLVMConstInt (IntPtrType (), 0, FALSE
);
5325 ji
->next
= cfg
->patch_info
;
5326 cfg
->patch_info
= ji
;
5328 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5329 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
5330 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
5331 if (!mono_aot_is_shared_got_offset (got_offset
)) {
5332 //mono_print_ji (ji);
5334 ctx
->has_got_access
= TRUE
;
5337 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5338 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
5339 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
5341 name
= get_aotconst_name (ji
->type
, ji
->data
.target
, got_offset
);
5342 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, name
);
5344 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5345 if (!cfg
->llvm_only
)
5346 set_invariant_load_flag (values
[ins
->dreg
]);
5349 case OP_NOT_REACHED
:
5350 LLVMBuildUnreachable (builder
);
5351 has_terminator
= TRUE
;
5352 g_assert (bb
->block_num
< cfg
->max_block_num
);
5353 ctx
->unreachable
[bb
->block_num
] = TRUE
;
5354 /* Might have instructions after this */
5356 MonoInst
*next
= ins
->next
;
5358 * FIXME: If later code uses the regs defined by these instructions,
5359 * compilation will fail.
5361 MONO_DELETE_INS (bb
, next
);
5365 MonoInst
*var
= ins
->inst_i0
;
5367 if (var
->opcode
== OP_VTARG_ADDR
) {
5368 /* The variable contains the vtype address */
5369 values
[ins
->dreg
] = values
[var
->dreg
];
5370 } else if (var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5371 values
[ins
->dreg
] = emit_gsharedvt_ldaddr (ctx
, var
->dreg
);
5373 values
[ins
->dreg
] = addresses
[var
->dreg
];
5378 LLVMValueRef args
[1];
5380 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5381 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sin.f64"), args
, 1, dname
);
5385 LLVMValueRef args
[1];
5387 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5388 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.cos.f64"), args
, 1, dname
);
5392 LLVMValueRef args
[1];
5394 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5395 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sqrt.f64"), args
, 1, dname
);
5399 LLVMValueRef args
[1];
5401 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5402 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "fabs"), args
, 1, dname
);
5416 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5417 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5419 switch (ins
->opcode
) {
5422 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
5426 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
5430 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
5434 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
5437 g_assert_not_reached ();
5440 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
5445 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5446 * hack is necessary (for now).
5449 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5451 #define ARM64_ATOMIC_FENCE_FIX
5454 case OP_ATOMIC_EXCHANGE_I4
:
5455 case OP_ATOMIC_EXCHANGE_I8
: {
5456 LLVMValueRef args
[2];
5459 if (ins
->opcode
== OP_ATOMIC_EXCHANGE_I4
)
5460 t
= LLVMInt32Type ();
5462 t
= LLVMInt64Type ();
5464 g_assert (ins
->inst_offset
== 0);
5466 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5467 args
[1] = convert (ctx
, rhs
, t
);
5469 ARM64_ATOMIC_FENCE_FIX
;
5470 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
5471 ARM64_ATOMIC_FENCE_FIX
;
5474 case OP_ATOMIC_ADD_I4
:
5475 case OP_ATOMIC_ADD_I8
: {
5476 LLVMValueRef args
[2];
5479 if (ins
->opcode
== OP_ATOMIC_ADD_I4
)
5480 t
= LLVMInt32Type ();
5482 t
= LLVMInt64Type ();
5484 g_assert (ins
->inst_offset
== 0);
5486 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5487 args
[1] = convert (ctx
, rhs
, t
);
5488 ARM64_ATOMIC_FENCE_FIX
;
5489 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
5490 ARM64_ATOMIC_FENCE_FIX
;
5493 case OP_ATOMIC_CAS_I4
:
5494 case OP_ATOMIC_CAS_I8
: {
5495 LLVMValueRef args
[3], val
;
5498 if (ins
->opcode
== OP_ATOMIC_CAS_I4
)
5499 t
= LLVMInt32Type ();
5501 t
= LLVMInt64Type ();
5503 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5505 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
5507 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
5508 ARM64_ATOMIC_FENCE_FIX
;
5509 val
= mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
5510 ARM64_ATOMIC_FENCE_FIX
;
5511 /* cmpxchg returns a pair */
5512 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, "");
5515 case OP_MEMORY_BARRIER
: {
5516 mono_llvm_build_fence (builder
, (BarrierKind
) ins
->backend
.memory_barrier_kind
);
5519 case OP_ATOMIC_LOAD_I1
:
5520 case OP_ATOMIC_LOAD_I2
:
5521 case OP_ATOMIC_LOAD_I4
:
5522 case OP_ATOMIC_LOAD_I8
:
5523 case OP_ATOMIC_LOAD_U1
:
5524 case OP_ATOMIC_LOAD_U2
:
5525 case OP_ATOMIC_LOAD_U4
:
5526 case OP_ATOMIC_LOAD_U8
:
5527 case OP_ATOMIC_LOAD_R4
:
5528 case OP_ATOMIC_LOAD_R8
: {
5529 #if LLVM_API_VERSION > 100
5531 gboolean sext
, zext
;
5533 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5534 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5535 LLVMValueRef index
, addr
;
5537 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5542 if (ins
->inst_offset
!= 0) {
5543 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5544 addr
= LLVMBuildGEP (builder
, convert (ctx
, lhs
, LLVMPointerType (t
, 0)), &index
, 1, "");
5549 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5551 ARM64_ATOMIC_FENCE_FIX
;
5552 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, lhs
, dname
, is_volatile
, barrier
);
5553 ARM64_ATOMIC_FENCE_FIX
;
5556 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5558 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5561 set_failure (ctx
, "atomic mono.load intrinsic");
5565 case OP_ATOMIC_STORE_I1
:
5566 case OP_ATOMIC_STORE_I2
:
5567 case OP_ATOMIC_STORE_I4
:
5568 case OP_ATOMIC_STORE_I8
:
5569 case OP_ATOMIC_STORE_U1
:
5570 case OP_ATOMIC_STORE_U2
:
5571 case OP_ATOMIC_STORE_U4
:
5572 case OP_ATOMIC_STORE_U8
:
5573 case OP_ATOMIC_STORE_R4
:
5574 case OP_ATOMIC_STORE_R8
: {
5576 gboolean sext
, zext
;
5578 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5579 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5580 LLVMValueRef index
, addr
, value
, base
;
5582 #if LLVM_API_VERSION < 100
5583 if (!cfg
->llvm_only
) {
5584 set_failure (ctx
, "atomic mono.store intrinsic");
5589 if (!values
[ins
->inst_destbasereg
]) {
5590 set_failure (ctx
, "inst_destbasereg");
5594 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5596 base
= values
[ins
->inst_destbasereg
];
5597 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5598 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5599 value
= convert (ctx
, values
[ins
->sreg1
], t
);
5601 ARM64_ATOMIC_FENCE_FIX
;
5602 emit_store_general (ctx
, bb
, &builder
, size
, value
, addr
, base
, is_volatile
, barrier
);
5603 ARM64_ATOMIC_FENCE_FIX
;
5606 case OP_RELAXED_NOP
: {
5607 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5608 emit_call (ctx
, bb
, &builder
, get_intrinsic (ctx
, "llvm.x86.sse2.pause"), NULL
, 0);
5615 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5617 // 257 == FS segment register
5618 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5620 // 256 == GS segment register
5621 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5624 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
5625 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5626 /* See mono_amd64_emit_tls_get () */
5627 int offset
= mono_amd64_get_tls_gs_offset () + (ins
->inst_offset
* 8);
5629 // 256 == GS segment register
5630 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5631 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), offset
, TRUE
), ptrtype
, ""), "");
5633 set_failure (ctx
, "opcode tls-get");
5639 case OP_TLS_GET_REG
: {
5640 #if defined(TARGET_AMD64) && defined(__linux__)
5641 // 257 == FS segment register
5642 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5643 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt64Type ()), ptrtype
, ""), "");
5644 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5645 /* See emit_tls_get_reg () */
5646 // 256 == GS segment register
5647 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5648 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), ptrtype
, ""), "");
5650 set_failure (ctx
, "opcode tls-get");
5656 case OP_TLS_SET_REG
: {
5657 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5658 /* See emit_tls_get_reg () */
5659 // 256 == GS segment register
5660 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5661 LLVMBuildStore (builder
, convert (ctx
, lhs
, IntPtrType ()), LLVMBuildIntToPtr (builder
, convert (ctx
, rhs
, LLVMInt32Type ()), ptrtype
, ""));
5663 set_failure (ctx
, "opcode tls-set-reg");
5668 case OP_GC_SAFE_POINT
: {
5669 LLVMValueRef val
, cmp
, callee
;
5670 LLVMBasicBlockRef poll_bb
, cont_bb
;
5671 static LLVMTypeRef sig
;
5672 const char *icall_name
= "mono_threads_state_poll";
5675 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
5679 * mono_threads_state_poll ();
5680 * FIXME: Use a preserveall wrapper
5682 val
= mono_llvm_build_load (builder
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
5683 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
5684 poll_bb
= gen_bb (ctx
, "POLL_BB");
5685 cont_bb
= gen_bb (ctx
, "CONT_BB");
5686 LLVMBuildCondBr (builder
, cmp
, cont_bb
, poll_bb
);
5688 ctx
->builder
= builder
= create_builder (ctx
);
5689 LLVMPositionBuilderAtEnd (builder
, poll_bb
);
5691 if (ctx
->cfg
->compile_aot
) {
5692 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5694 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5695 callee
= emit_jit_callee (ctx
, icall_name
, sig
, target
);
5697 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
5698 LLVMBuildBr (builder
, cont_bb
);
5700 ctx
->builder
= builder
= create_builder (ctx
);
5701 LLVMPositionBuilderAtEnd (builder
, cont_bb
);
5702 ctx
->bblocks
[bb
->block_num
].end_bblock
= cont_bb
;
5710 case OP_IADD_OVF_UN
:
5712 case OP_ISUB_OVF_UN
:
5714 case OP_IMUL_OVF_UN
:
5716 case OP_LADD_OVF_UN
:
5718 case OP_LSUB_OVF_UN
:
5720 case OP_LMUL_OVF_UN
:
5722 LLVMValueRef args
[2], val
, ovf
, func
;
5724 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
5725 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
5726 func
= get_intrinsic (ctx
, ovf_op_to_intrins (ins
->opcode
));
5728 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
5729 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
5730 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
5731 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
5734 builder
= ctx
->builder
;
5740 * We currently model them using arrays. Promotion to local vregs is
5741 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5742 * so we always have an entry in cfg->varinfo for them.
5743 * FIXME: Is this needed ?
5746 MonoClass
*klass
= ins
->klass
;
5747 LLVMValueRef args
[5];
5751 set_failure (ctx
, "!klass");
5755 if (!addresses
[ins
->dreg
])
5756 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5757 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5758 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5759 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5761 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5762 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5763 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5766 case OP_DUMMY_VZERO
:
5769 case OP_STOREV_MEMBASE
:
5770 case OP_LOADV_MEMBASE
:
5772 MonoClass
*klass
= ins
->klass
;
5773 LLVMValueRef src
= NULL
, dst
, args
[5];
5774 gboolean done
= FALSE
;
5778 set_failure (ctx
, "!klass");
5782 if (mini_is_gsharedvt_klass (klass
)) {
5784 set_failure (ctx
, "gsharedvt");
5788 switch (ins
->opcode
) {
5789 case OP_STOREV_MEMBASE
:
5790 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
&&
5791 LLVMGetInstructionOpcode (values
[ins
->inst_destbasereg
]) != LLVMAlloca
) {
5792 /* Decomposed earlier */
5793 g_assert_not_reached ();
5796 if (!addresses
[ins
->sreg1
]) {
5798 g_assert (values
[ins
->sreg1
]);
5799 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));
5800 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
5803 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5804 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5807 case OP_LOADV_MEMBASE
:
5808 if (!addresses
[ins
->dreg
])
5809 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5810 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5811 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5814 if (!addresses
[ins
->sreg1
])
5815 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
5816 if (!addresses
[ins
->dreg
])
5817 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5818 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5819 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5822 g_assert_not_reached ();
5832 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5833 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5835 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5836 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5837 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memcpy.p0i8.p0i8.i32"), args
, 5, "");
5840 case OP_LLVM_OUTARG_VT
: {
5841 LLVMArgInfo
*ainfo
= (LLVMArgInfo
*)ins
->inst_p0
;
5842 MonoType
*t
= mini_get_underlying_type (ins
->inst_vtype
);
5844 if (ainfo
->storage
== LLVMArgGsharedvtVariable
) {
5845 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
5847 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5848 addresses
[ins
->dreg
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), LLVMPointerType (IntPtrType (), 0));
5850 g_assert (addresses
[ins
->sreg1
]);
5851 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5853 } else if (ainfo
->storage
== LLVMArgGsharedvtFixed
) {
5854 if (!addresses
[ins
->sreg1
]) {
5855 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5856 g_assert (values
[ins
->sreg1
]);
5858 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (LLVMTypeOf (addresses
[ins
->sreg1
]))), addresses
[ins
->sreg1
]);
5859 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5861 if (!addresses
[ins
->sreg1
]) {
5862 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5863 g_assert (values
[ins
->sreg1
]);
5864 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, t
)), addresses
[ins
->sreg1
]);
5866 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5870 case OP_OBJC_GET_SELECTOR
: {
5871 const char *name
= (const char*)ins
->inst_p0
;
5874 if (!ctx
->module
->objc_selector_to_var
)
5875 ctx
->module
->objc_selector_to_var
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
5876 var
= g_hash_table_lookup (ctx
->module
->objc_selector_to_var
, name
);
5878 LLVMValueRef indexes
[16];
5880 LLVMValueRef name_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), strlen (name
) + 1), "@OBJC_METH_VAR_NAME_");
5881 LLVMSetInitializer (name_var
, mono_llvm_create_constant_data_array ((const uint8_t*)name
, strlen (name
) + 1));
5882 LLVMSetLinkage (name_var
, LLVMPrivateLinkage
);
5883 LLVMSetSection (name_var
, "__TEXT,__objc_methname,cstring_literals");
5884 mark_as_used (ctx
->module
, name_var
);
5886 LLVMValueRef ref_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5888 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5889 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5890 LLVMSetInitializer (ref_var
, LLVMConstGEP (name_var
, indexes
, 2));
5891 LLVMSetLinkage (ref_var
, LLVMPrivateLinkage
);
5892 LLVMSetExternallyInitialized (ref_var
, TRUE
);
5893 LLVMSetSection (ref_var
, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5894 LLVMSetAlignment (ref_var
, sizeof (mgreg_t
));
5895 mark_as_used (ctx
->module
, ref_var
);
5897 g_hash_table_insert (ctx
->module
->objc_selector_to_var
, g_strdup (name
), ref_var
);
5901 values
[ins
->dreg
] = LLVMBuildLoad (builder
, var
, "");
5908 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5910 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
5913 case OP_LOADX_MEMBASE
: {
5914 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
5917 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5918 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
5921 case OP_STOREX_MEMBASE
: {
5922 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
5925 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5926 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
5933 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
5937 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
5943 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
5947 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
5951 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
5955 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
5958 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
5961 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
5964 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
5968 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
5979 LLVMValueRef v
= NULL
;
5981 switch (ins
->opcode
) {
5986 t
= LLVMVectorType (LLVMInt32Type (), 4);
5987 rt
= LLVMVectorType (LLVMFloatType (), 4);
5993 t
= LLVMVectorType (LLVMInt64Type (), 2);
5994 rt
= LLVMVectorType (LLVMDoubleType (), 2);
5997 t
= LLVMInt32Type ();
5998 rt
= LLVMInt32Type ();
5999 g_assert_not_reached ();
6002 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6003 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
6004 switch (ins
->opcode
) {
6007 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
6011 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
6015 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
6019 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
6022 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
6028 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntULT
, lhs
, rhs
, "");
6029 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6035 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntUGT
, lhs
, rhs
, "");
6036 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6040 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntSLT
, lhs
, rhs
, "");
6041 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
6058 case OP_PADDB_SAT_UN
:
6059 case OP_PADDW_SAT_UN
:
6060 case OP_PSUBB_SAT_UN
:
6061 case OP_PSUBW_SAT_UN
:
6069 case OP_PMULW_HIGH_UN
: {
6070 LLVMValueRef args
[2];
6075 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6082 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6086 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntSGT
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
6094 case OP_EXTRACTX_U2
:
6096 case OP_EXTRACT_U1
: {
6098 gboolean zext
= FALSE
;
6100 t
= simd_op_to_llvm_type (ins
->opcode
);
6102 switch (ins
->opcode
) {
6110 case OP_EXTRACTX_U2
:
6115 t
= LLVMInt32Type ();
6116 g_assert_not_reached ();
6119 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6120 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
6122 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
6131 case OP_EXPAND_R8
: {
6132 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6133 LLVMValueRef mask
[16], v
;
6136 for (i
= 0; i
< 16; ++i
)
6137 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6139 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
6141 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6142 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
6147 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6150 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6153 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6156 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6159 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6162 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6166 // Requires a later llvm version
6168 LLVMValueRef indexes
[16];
6170 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6171 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6172 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6173 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6174 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6178 LLVMValueRef indexes
[16];
6180 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6181 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
6182 LLVMValueRef mask
= LLVMConstVector (indexes
, 2);
6183 LLVMValueRef shuffle
= LLVMBuildShuffleVector (builder
, lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), mask
, "");
6184 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, shuffle
, LLVMVectorType (LLVMDoubleType (), 2), dname
);
6188 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMVectorType (LLVMInt32Type (), 4), dname
);
6200 case OP_EXTRACT_MASK
:
6207 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
6209 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
6214 LLVMRealPredicate op
;
6216 switch (ins
->inst_c0
) {
6226 case SIMD_COMP_UNORD
:
6242 g_assert_not_reached ();
6245 LLVMValueRef cmp
= LLVMBuildFCmp (builder
, op
, lhs
, rhs
, "");
6246 if (ins
->opcode
== OP_COMPPD
)
6247 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs
), "");
6249 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs
), "");
6253 /* This is only used for implementing shifts by non-immediate */
6254 values
[ins
->dreg
] = lhs
;
6265 LLVMValueRef args
[3];
6268 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
6270 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6281 case OP_PSHLQ_REG
: {
6282 LLVMValueRef args
[3];
6285 args
[1] = values
[ins
->sreg2
];
6287 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6294 case OP_PSHUFLEW_LOW
:
6295 case OP_PSHUFLEW_HIGH
: {
6297 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
6298 int i
, mask_size
= 0;
6299 int imask
= ins
->inst_c0
;
6301 /* Convert the x86 shuffle mask to LLVM's */
6302 switch (ins
->opcode
) {
6305 mask
[0] = ((imask
>> 0) & 3);
6306 mask
[1] = ((imask
>> 2) & 3);
6307 mask
[2] = ((imask
>> 4) & 3) + 4;
6308 mask
[3] = ((imask
>> 6) & 3) + 4;
6309 v1
= values
[ins
->sreg1
];
6310 v2
= values
[ins
->sreg2
];
6314 mask
[0] = ((imask
>> 0) & 1);
6315 mask
[1] = ((imask
>> 1) & 1) + 2;
6316 v1
= values
[ins
->sreg1
];
6317 v2
= values
[ins
->sreg2
];
6319 case OP_PSHUFLEW_LOW
:
6321 mask
[0] = ((imask
>> 0) & 3);
6322 mask
[1] = ((imask
>> 2) & 3);
6323 mask
[2] = ((imask
>> 4) & 3);
6324 mask
[3] = ((imask
>> 6) & 3);
6329 v1
= values
[ins
->sreg1
];
6330 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6332 case OP_PSHUFLEW_HIGH
:
6338 mask
[4] = 4 + ((imask
>> 0) & 3);
6339 mask
[5] = 4 + ((imask
>> 2) & 3);
6340 mask
[6] = 4 + ((imask
>> 4) & 3);
6341 mask
[7] = 4 + ((imask
>> 6) & 3);
6342 v1
= values
[ins
->sreg1
];
6343 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6347 mask
[0] = ((imask
>> 0) & 3);
6348 mask
[1] = ((imask
>> 2) & 3);
6349 mask
[2] = ((imask
>> 4) & 3);
6350 mask
[3] = ((imask
>> 6) & 3);
6351 v1
= values
[ins
->sreg1
];
6352 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6355 g_assert_not_reached ();
6357 for (i
= 0; i
< mask_size
; ++i
)
6358 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6360 values
[ins
->dreg
] =
6361 LLVMBuildShuffleVector (builder
, v1
, v2
,
6362 LLVMConstVector (mask_values
, mask_size
), dname
);
6366 case OP_UNPACK_LOWB
:
6367 case OP_UNPACK_LOWW
:
6368 case OP_UNPACK_LOWD
:
6369 case OP_UNPACK_LOWQ
:
6370 case OP_UNPACK_LOWPS
:
6371 case OP_UNPACK_LOWPD
:
6372 case OP_UNPACK_HIGHB
:
6373 case OP_UNPACK_HIGHW
:
6374 case OP_UNPACK_HIGHD
:
6375 case OP_UNPACK_HIGHQ
:
6376 case OP_UNPACK_HIGHPS
:
6377 case OP_UNPACK_HIGHPD
: {
6379 LLVMValueRef mask_values
[16];
6380 int i
, mask_size
= 0;
6381 gboolean low
= FALSE
;
6383 switch (ins
->opcode
) {
6384 case OP_UNPACK_LOWB
:
6388 case OP_UNPACK_LOWW
:
6392 case OP_UNPACK_LOWD
:
6393 case OP_UNPACK_LOWPS
:
6397 case OP_UNPACK_LOWQ
:
6398 case OP_UNPACK_LOWPD
:
6402 case OP_UNPACK_HIGHB
:
6405 case OP_UNPACK_HIGHW
:
6408 case OP_UNPACK_HIGHD
:
6409 case OP_UNPACK_HIGHPS
:
6412 case OP_UNPACK_HIGHQ
:
6413 case OP_UNPACK_HIGHPD
:
6417 g_assert_not_reached ();
6421 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6423 mask
[(i
* 2) + 1] = mask_size
+ i
;
6426 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6427 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
6428 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
6432 for (i
= 0; i
< mask_size
; ++i
)
6433 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6435 values
[ins
->dreg
] =
6436 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
6437 LLVMConstVector (mask_values
, mask_size
), dname
);
6442 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6443 LLVMValueRef v
, val
;
6445 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6446 val
= LLVMConstNull (t
);
6447 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6448 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
6450 values
[ins
->dreg
] = val
;
6454 case OP_DUPPS_HIGH
: {
6455 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6456 LLVMValueRef v1
, v2
, val
;
6459 if (ins
->opcode
== OP_DUPPS_LOW
) {
6460 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6461 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6463 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6464 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6466 val
= LLVMConstNull (t
);
6467 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6468 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6469 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6470 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6472 values
[ins
->dreg
] = val
;
6477 LLVMValueRef args
[3];
6481 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6482 args
[2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE
);
6484 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 3, dname
);
6494 * EXCEPTION HANDLING
6496 case OP_IMPLICIT_EXCEPTION
:
6497 /* This marks a place where an implicit exception can happen */
6498 if (bb
->region
!= -1)
6499 set_failure (ctx
, "implicit-exception");
6503 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
6504 if (ctx
->llvm_only
) {
6505 emit_llvmonly_throw (ctx
, bb
, rethrow
, lhs
);
6506 has_terminator
= TRUE
;
6507 ctx
->unreachable
[bb
->block_num
] = TRUE
;
6509 emit_throw (ctx
, bb
, rethrow
, lhs
);
6510 builder
= ctx
->builder
;
6514 case OP_CALL_HANDLER
: {
6516 * We don't 'call' handlers, but instead simply branch to them.
6517 * The code generated by ENDFINALLY will branch back to us.
6519 LLVMBasicBlockRef noex_bb
;
6521 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
6523 bb_list
= info
->call_handler_return_bbs
;
6526 * Set the indicator variable for the finally clause.
6528 lhs
= info
->finally_ind
;
6530 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
6532 /* Branch to the finally clause */
6533 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
6535 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
6536 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
6538 builder
= ctx
->builder
= create_builder (ctx
);
6539 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
6541 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
6544 case OP_START_HANDLER
: {
6547 case OP_ENDFINALLY
: {
6548 LLVMBasicBlockRef resume_bb
;
6549 MonoBasicBlock
*handler_bb
;
6550 LLVMValueRef val
, switch_ins
, callee
;
6554 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
6555 g_assert (handler_bb
);
6556 info
= &bblocks
[handler_bb
->block_num
];
6557 lhs
= info
->finally_ind
;
6560 bb_list
= info
->call_handler_return_bbs
;
6562 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
6564 /* Load the finally variable */
6565 val
= LLVMBuildLoad (builder
, lhs
, "");
6567 /* Reset the variable */
6568 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
6570 /* Branch to either resume_bb, or to the bblocks in bb_list */
6571 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
6573 * The other targets are added at the end to handle OP_CALL_HANDLER
6574 * opcodes processed later.
6576 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
6578 builder
= ctx
->builder
= create_builder (ctx
);
6579 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
6581 if (ctx
->llvm_only
) {
6582 emit_resume_eh (ctx
, bb
);
6584 if (ctx
->cfg
->compile_aot
) {
6585 callee
= get_callee (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
6587 #if LLVM_API_VERSION > 100
6588 MonoJitICallInfo
*info
;
6590 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6592 gpointer target
= (void*)info
->func
;
6593 LLVMTypeRef icall_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
6594 callee
= emit_jit_callee (ctx
, "llvm_resume_unwind_trampoline", icall_sig
, target
);
6596 callee
= LLVMGetNamedFunction (ctx
->lmodule
, "llvm_resume_unwind_trampoline");
6599 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
6600 LLVMBuildUnreachable (builder
);
6603 has_terminator
= TRUE
;
6606 case OP_IL_SEQ_POINT
:
6611 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
6612 set_failure (ctx
, reason
);
6620 /* Convert the value to the type required by phi nodes */
6621 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
6622 if (ctx
->is_vphi
[ins
->dreg
])
6624 values
[ins
->dreg
] = addresses
[ins
->dreg
];
6626 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
6629 /* Add stores for volatile variables */
6630 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
6631 emit_volatile_store (ctx
, ins
->dreg
);
6637 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0)) {
6638 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
6641 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
) {
6642 emit_dbg_loc (ctx
, builder
, cfg
->header
->code
+ cfg
->header
->code_size
- 1);
6643 LLVMBuildRetVoid (builder
);
6646 if (bb
== cfg
->bb_entry
)
6647 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
6651 * mono_llvm_check_method_supported:
6653 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6654 * compiling a method twice.
6657 mono_llvm_check_method_supported (MonoCompile
*cfg
)
6664 if (cfg
->method
->save_lmf
) {
6665 cfg
->exception_message
= g_strdup ("lmf");
6666 cfg
->disable_llvm
= TRUE
;
6668 if (cfg
->disable_llvm
)
6672 * Nested clauses where one of the clauses is a finally clause is
6673 * not supported, because LLVM can't figure out the control flow,
6674 * probably because we resume exception handling by calling our
6675 * own function instead of using the 'resume' llvm instruction.
6677 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
6678 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
6679 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
6680 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
6682 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6683 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
6684 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6685 cfg
->exception_message
= g_strdup ("nested clauses");
6686 cfg
->disable_llvm
= TRUE
;
6691 if (cfg
->disable_llvm
)
6695 if (cfg
->method
->dynamic
) {
6696 cfg
->exception_message
= g_strdup ("dynamic.");
6697 cfg
->disable_llvm
= TRUE
;
6699 if (cfg
->disable_llvm
)
6703 static LLVMCallInfo
*
6704 get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
6706 LLVMCallInfo
*linfo
;
6709 if (cfg
->gsharedvt
&& cfg
->llvm_only
&& mini_is_gsharedvt_variable_signature (sig
)) {
6713 * Gsharedvt methods have the following calling convention:
6714 * - all arguments are passed by ref, even non generic ones
6715 * - the return value is returned by ref too, using a vret
6716 * argument passed after 'this'.
6718 n
= sig
->param_count
+ sig
->hasthis
;
6719 linfo
= (LLVMCallInfo
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
6723 linfo
->args
[pindex
++].storage
= LLVMArgNormal
;
6725 if (sig
->ret
->type
!= MONO_TYPE_VOID
) {
6726 if (mini_is_gsharedvt_variable_type (sig
->ret
))
6727 linfo
->ret
.storage
= LLVMArgGsharedvtVariable
;
6728 else if (mini_type_is_vtype (sig
->ret
))
6729 linfo
->ret
.storage
= LLVMArgGsharedvtFixedVtype
;
6731 linfo
->ret
.storage
= LLVMArgGsharedvtFixed
;
6732 linfo
->vret_arg_index
= pindex
;
6734 linfo
->ret
.storage
= LLVMArgNone
;
6737 for (i
= 0; i
< sig
->param_count
; ++i
) {
6738 if (sig
->params
[i
]->byref
)
6739 linfo
->args
[pindex
].storage
= LLVMArgNormal
;
6740 else if (mini_is_gsharedvt_variable_type (sig
->params
[i
]))
6741 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtVariable
;
6742 else if (mini_type_is_vtype (sig
->params
[i
]))
6743 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixedVtype
;
6745 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixed
;
6746 linfo
->args
[pindex
].type
= sig
->params
[i
];
6753 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
6754 for (i
= 0; i
< sig
->param_count
; ++i
)
6755 linfo
->args
[i
+ sig
->hasthis
].type
= sig
->params
[i
];
6761 emit_method_inner (EmitContext
*ctx
);
6764 free_ctx (EmitContext
*ctx
)
6768 g_free (ctx
->values
);
6769 g_free (ctx
->addresses
);
6770 g_free (ctx
->vreg_types
);
6771 g_free (ctx
->is_vphi
);
6772 g_free (ctx
->vreg_cli_types
);
6773 g_free (ctx
->is_dead
);
6774 g_free (ctx
->unreachable
);
6775 g_ptr_array_free (ctx
->phi_values
, TRUE
);
6776 g_free (ctx
->bblocks
);
6777 g_hash_table_destroy (ctx
->region_to_handler
);
6778 g_hash_table_destroy (ctx
->clause_to_handler
);
6779 g_hash_table_destroy (ctx
->jit_callees
);
6781 GHashTableIter iter
;
6782 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
6783 while (g_hash_table_iter_next (&iter
, NULL
, (gpointer
)&l
))
6786 g_hash_table_destroy (ctx
->method_to_callers
);
6788 g_free (ctx
->method_name
);
6789 g_ptr_array_free (ctx
->bblock_list
, TRUE
);
6791 for (l
= ctx
->builders
; l
; l
= l
->next
) {
6792 LLVMBuilderRef builder
= (LLVMBuilderRef
)l
->data
;
6793 LLVMDisposeBuilder (builder
);
6800 * mono_llvm_emit_method:
6802 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6805 mono_llvm_emit_method (MonoCompile
*cfg
)
6809 gboolean is_linkonce
= FALSE
;
6812 /* The code below might acquire the loader lock, so use it for global locking */
6813 mono_loader_lock ();
6815 /* Used to communicate with the callbacks */
6816 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
6818 ctx
= g_new0 (EmitContext
, 1);
6820 ctx
->mempool
= cfg
->mempool
;
6823 * This maps vregs to the LLVM instruction defining them
6825 ctx
->values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6827 * This maps vregs for volatile variables to the LLVM instruction defining their
6830 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6831 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
6832 ctx
->is_vphi
= g_new0 (gboolean
, cfg
->next_vreg
);
6833 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
6834 ctx
->phi_values
= g_ptr_array_sized_new (256);
6836 * This signals whenever the vreg was defined by a phi node with no input vars
6837 * (i.e. all its input bblocks end with NOT_REACHABLE).
6839 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
6840 /* Whenever the bblock is unreachable */
6841 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
6842 ctx
->bblock_list
= g_ptr_array_sized_new (256);
6844 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
6845 ctx
->clause_to_handler
= g_hash_table_new (NULL
, NULL
);
6846 ctx
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
6847 ctx
->jit_callees
= g_hash_table_new (NULL
, NULL
);
6848 if (cfg
->compile_aot
) {
6849 ctx
->module
= &aot_module
;
6853 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6854 * linkage for them. This requires the following:
6855 * - the method needs to have a unique mangled name
6856 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6858 is_linkonce
= ctx
->module
->llvm_only
&& ctx
->module
->static_link
&& mono_aot_is_linkonce_method (cfg
->method
);
6860 method_name
= mono_aot_get_mangled_method_name (cfg
->method
);
6862 is_linkonce
= FALSE
;
6865 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6867 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6871 method_name
= mono_aot_get_method_name (cfg
);
6872 cfg
->llvm_method_name
= g_strdup (method_name
);
6874 init_jit_module (cfg
->domain
);
6875 ctx
->module
= (MonoLLVMModule
*)domain_jit_info (cfg
->domain
)->llvm_module
;
6876 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
6878 ctx
->method_name
= method_name
;
6879 ctx
->is_linkonce
= is_linkonce
;
6881 #if LLVM_API_VERSION > 100
6882 if (cfg
->compile_aot
)
6883 ctx
->lmodule
= ctx
->module
->lmodule
;
6885 ctx
->lmodule
= LLVMModuleCreateWithName ("jit-module");
6887 ctx
->lmodule
= ctx
->module
->lmodule
;
6889 ctx
->llvm_only
= ctx
->module
->llvm_only
;
6891 emit_method_inner (ctx
);
6893 if (!ctx_ok (ctx
)) {
6895 /* Need to add unused phi nodes as they can be referenced by other values */
6896 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "PHI_BB");
6897 LLVMBuilderRef builder
;
6899 builder
= create_builder (ctx
);
6900 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
6902 for (i
= 0; i
< ctx
->phi_values
->len
; ++i
) {
6903 LLVMValueRef v
= (LLVMValueRef
)g_ptr_array_index (ctx
->phi_values
, i
);
6904 if (LLVMGetInstructionParent (v
) == NULL
)
6905 LLVMInsertIntoBuilder (builder
, v
);
6908 LLVMDeleteFunction (ctx
->lmethod
);
6914 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
6916 mono_loader_unlock ();
6920 emit_method_inner (EmitContext
*ctx
)
6922 MonoCompile
*cfg
= ctx
->cfg
;
6923 MonoMethodSignature
*sig
;
6925 LLVMTypeRef method_type
;
6926 LLVMValueRef method
= NULL
;
6927 LLVMValueRef
*values
= ctx
->values
;
6928 int i
, max_block_num
, bb_index
;
6929 gboolean last
= FALSE
;
6930 LLVMCallInfo
*linfo
;
6931 LLVMModuleRef lmodule
= ctx
->lmodule
;
6933 GPtrArray
*bblock_list
= ctx
->bblock_list
;
6934 MonoMethodHeader
*header
;
6935 MonoExceptionClause
*clause
;
6938 if (cfg
->gsharedvt
&& !cfg
->llvm_only
) {
6939 set_failure (ctx
, "gsharedvt");
6945 static int count
= 0;
6948 if (g_getenv ("LLVM_COUNT")) {
6949 if (count
== atoi (g_getenv ("LLVM_COUNT"))) {
6950 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
6954 if (count
> atoi (g_getenv ("LLVM_COUNT"))) {
6955 set_failure (ctx
, "count");
6962 sig
= mono_method_signature (cfg
->method
);
6965 linfo
= get_llvm_call_info (cfg
, sig
);
6971 linfo
->rgctx_arg
= TRUE
;
6972 ctx
->method_type
= method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
);
6976 method
= LLVMAddFunction (lmodule
, ctx
->method_name
, method_type
);
6977 ctx
->lmethod
= method
;
6979 if (!cfg
->llvm_only
)
6980 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
6981 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
6983 LLVMAddFunctionAttr (method
, LLVMUWTable
);
6985 if (cfg
->compile_aot
) {
6986 LLVMSetLinkage (method
, LLVMInternalLinkage
);
6987 if (ctx
->module
->external_symbols
) {
6988 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6989 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
6991 if (ctx
->is_linkonce
) {
6992 LLVMSetLinkage (method
, LLVMLinkOnceAnyLinkage
);
6993 LLVMSetVisibility (method
, LLVMDefaultVisibility
);
6996 #if LLVM_API_VERSION > 100
6997 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6999 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
7003 if (cfg
->method
->save_lmf
&& !cfg
->llvm_only
) {
7004 set_failure (ctx
, "lmf");
7008 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
&& !cfg
->llvm_only
) {
7009 set_failure (ctx
, "pinvoke signature");
7013 header
= cfg
->header
;
7014 for (i
= 0; i
< header
->num_clauses
; ++i
) {
7015 clause
= &header
->clauses
[i
];
7016 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
) {
7017 set_failure (ctx
, "non-finally/catch clause.");
7021 if (header
->num_clauses
|| (cfg
->method
->iflags
& METHOD_IMPL_ATTRIBUTE_NOINLINING
) || cfg
->no_inline
)
7022 /* We can't handle inlined methods with clauses */
7023 LLVMAddFunctionAttr (method
, LLVMNoInlineAttribute
);
7025 if (linfo
->rgctx_arg
) {
7026 ctx
->rgctx_arg
= LLVMGetParam (method
, linfo
->rgctx_arg_pindex
);
7027 ctx
->rgctx_arg_pindex
= linfo
->rgctx_arg_pindex
;
7029 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7030 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7031 * CC_X86_64_Mono in X86CallingConv.td.
7033 if (!ctx
->llvm_only
)
7034 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
7035 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
7037 ctx
->rgctx_arg_pindex
= -1;
7039 if (cfg
->vret_addr
) {
7040 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, linfo
->vret_arg_pindex
);
7041 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
7042 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
7043 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
7044 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
7049 ctx
->this_arg_pindex
= linfo
->this_arg_pindex
;
7050 ctx
->this_arg
= LLVMGetParam (method
, linfo
->this_arg_pindex
);
7051 values
[cfg
->args
[0]->dreg
] = ctx
->this_arg
;
7052 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
7055 names
= g_new (char *, sig
->param_count
);
7056 mono_method_get_param_names (cfg
->method
, (const char **) names
);
7058 /* Set parameter names/attributes */
7059 for (i
= 0; i
< sig
->param_count
; ++i
) {
7060 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
7062 int pindex
= ainfo
->pindex
+ ainfo
->ndummy_fpargs
;
7065 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
) {
7066 name
= g_strdup_printf ("dummy_%d_%d", i
, j
);
7067 LLVMSetValueName (LLVMGetParam (method
, ainfo
->pindex
+ j
), name
);
7071 if (ainfo
->storage
== LLVMArgVtypeInReg
&& ainfo
->pair_storage
[0] == LLVMArgNone
&& ainfo
->pair_storage
[1] == LLVMArgNone
)
7074 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
7075 if (ainfo
->storage
== LLVMArgGsharedvtFixed
|| ainfo
->storage
== LLVMArgGsharedvtFixedVtype
) {
7076 if (names
[i
] && names
[i
][0] != '\0')
7077 name
= g_strdup_printf ("p_arg_%s", names
[i
]);
7079 name
= g_strdup_printf ("p_arg_%d", i
);
7081 if (names
[i
] && names
[i
][0] != '\0')
7082 name
= g_strdup_printf ("arg_%s", names
[i
]);
7084 name
= g_strdup_printf ("arg_%d", i
);
7086 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
7088 if (ainfo
->storage
== LLVMArgVtypeByVal
)
7089 LLVMAddAttribute (LLVMGetParam (method
, pindex
), LLVMByValAttribute
);
7091 if (ainfo
->storage
== LLVMArgVtypeByRef
) {
7093 cfg
->args
[i
+ sig
->hasthis
]->opcode
= OP_VTARG_ADDR
;
7098 if (ctx
->module
->emit_dwarf
&& cfg
->compile_aot
&& mono_debug_enabled ()) {
7099 ctx
->minfo
= mono_debug_lookup_method (cfg
->method
);
7100 ctx
->dbg_md
= emit_dbg_subprogram (ctx
, cfg
, method
, ctx
->method_name
);
7104 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
7105 max_block_num
= MAX (max_block_num
, bb
->block_num
);
7106 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
7108 /* Add branches between non-consecutive bblocks */
7109 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7110 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
7111 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
7113 MonoInst
*inst
= (MonoInst
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
7114 inst
->opcode
= OP_BR
;
7115 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
7116 mono_bblock_add_inst (bb
, inst
);
7121 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7122 * was later optimized away, so clear these flags, and add them back for the still
7123 * present OP_LDADDR instructions.
7125 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
7128 ins
= get_vreg_to_inst (cfg
, i
);
7129 if (ins
&& ins
!= cfg
->rgctx_var
)
7130 ins
->flags
&= ~MONO_INST_INDIRECT
;
7134 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7136 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7138 LLVMBuilderRef builder
;
7140 char dname_buf
[128];
7142 builder
= create_builder (ctx
);
7144 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
7145 switch (ins
->opcode
) {
7150 LLVMTypeRef phi_type
= llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
7155 if (ins
->opcode
== OP_VPHI
) {
7156 /* Treat valuetype PHI nodes as operating on the address itself */
7157 g_assert (ins
->klass
);
7158 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
7162 * Have to precreate these, as they can be referenced by
7163 * earlier instructions.
7165 sprintf (dname_buf
, "t%d", ins
->dreg
);
7167 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
7169 if (ins
->opcode
== OP_VPHI
)
7170 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
7172 g_ptr_array_add (ctx
->phi_values
, values
[ins
->dreg
]);
7175 * Set the expected type of the incoming arguments since these have
7176 * to have the same type.
7178 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
7179 int sreg1
= ins
->inst_phi_args
[i
+ 1];
7182 if (ins
->opcode
== OP_VPHI
)
7183 ctx
->is_vphi
[sreg1
] = TRUE
;
7184 ctx
->vreg_types
[sreg1
] = phi_type
;
7190 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
7199 * Create an ordering for bblocks, use the depth first order first, then
7200 * put the exception handling bblocks last.
7202 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
7203 bb
= cfg
->bblocks
[bb_index
];
7204 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
7205 g_ptr_array_add (bblock_list
, bb
);
7206 bblocks
[bb
->block_num
].added
= TRUE
;
7210 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7211 if (!bblocks
[bb
->block_num
].added
)
7212 g_ptr_array_add (bblock_list
, bb
);
7216 * Second pass: generate code.
7219 LLVMBuilderRef entry_builder
= create_builder (ctx
);
7220 LLVMBasicBlockRef entry_bb
= get_bb (ctx
, cfg
->bb_entry
);
7221 LLVMPositionBuilderAtEnd (entry_builder
, entry_bb
);
7222 emit_entry_bb (ctx
, entry_builder
);
7224 // Make landing pads first
7225 ctx
->exc_meta
= g_hash_table_new_full (NULL
, NULL
, NULL
, NULL
);
7227 if (ctx
->llvm_only
) {
7228 size_t group_index
= 0;
7229 while (group_index
< cfg
->header
->num_clauses
) {
7231 size_t cursor
= group_index
;
7232 while (cursor
< cfg
->header
->num_clauses
&&
7233 CLAUSE_START (&cfg
->header
->clauses
[cursor
]) == CLAUSE_START (&cfg
->header
->clauses
[group_index
]) &&
7234 CLAUSE_END (&cfg
->header
->clauses
[cursor
]) == CLAUSE_END (&cfg
->header
->clauses
[group_index
])) {
7239 LLVMBasicBlockRef lpad_bb
= emit_landing_pad (ctx
, group_index
, count
);
7240 intptr_t key
= CLAUSE_END (&cfg
->header
->clauses
[group_index
]);
7241 g_hash_table_insert (ctx
->exc_meta
, (gpointer
)key
, lpad_bb
);
7243 group_index
= cursor
;
7247 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
7248 bb
= (MonoBasicBlock
*)g_ptr_array_index (bblock_list
, bb_index
);
7250 // Prune unreachable mono BBs.
7251 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
7254 process_bb (ctx
, bb
);
7258 g_hash_table_destroy (ctx
->exc_meta
);
7260 mono_memory_barrier ();
7262 /* Add incoming phi values */
7263 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7264 GSList
*l
, *ins_list
;
7266 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7268 for (l
= ins_list
; l
; l
= l
->next
) {
7269 PhiNode
*node
= (PhiNode
*)l
->data
;
7270 MonoInst
*phi
= node
->phi
;
7271 int sreg1
= node
->sreg
;
7272 LLVMBasicBlockRef in_bb
;
7277 in_bb
= get_end_bb (ctx
, node
->in_bb
);
7279 if (ctx
->unreachable
[node
->in_bb
->block_num
])
7282 if (!values
[sreg1
]) {
7283 /* Can happen with values in EH clauses */
7284 set_failure (ctx
, "incoming phi sreg1");
7288 if (phi
->opcode
== OP_VPHI
) {
7289 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7290 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
7292 if (LLVMTypeOf (values
[sreg1
]) != LLVMTypeOf (values
[phi
->dreg
])) {
7293 set_failure (ctx
, "incoming phi arg type mismatch");
7296 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7297 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
7302 /* Nullify empty phi instructions */
7303 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7304 GSList
*l
, *ins_list
;
7306 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7308 for (l
= ins_list
; l
; l
= l
->next
) {
7309 PhiNode
*node
= (PhiNode
*)l
->data
;
7310 MonoInst
*phi
= node
->phi
;
7311 LLVMValueRef phi_ins
= values
[phi
->dreg
];
7314 /* Already removed */
7317 if (LLVMCountIncoming (phi_ins
) == 0) {
7318 mono_llvm_replace_uses_of (phi_ins
, LLVMConstNull (LLVMTypeOf (phi_ins
)));
7319 LLVMInstructionEraseFromParent (phi_ins
);
7320 values
[phi
->dreg
] = NULL
;
7325 /* Create the SWITCH statements for ENDFINALLY instructions */
7326 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7327 BBInfo
*info
= &bblocks
[bb
->block_num
];
7329 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
7330 LLVMValueRef switch_ins
= (LLVMValueRef
)l
->data
;
7331 GSList
*bb_list
= info
->call_handler_return_bbs
;
7333 GSList
*bb_list_iter
;
7335 for (bb_list_iter
= bb_list
; bb_list_iter
; bb_list_iter
= g_slist_next (bb_list_iter
)) {
7336 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), (LLVMBasicBlockRef
)bb_list_iter
->data
);
7342 /* Initialize the method if needed */
7343 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
7344 // FIXME: Add more shared got entries
7345 ctx
->builder
= create_builder (ctx
);
7346 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->init_bb
);
7348 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
7350 // FIXME: beforefieldinit
7352 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7353 * in load_method ().
7355 if ((ctx
->has_got_access
|| mono_class_get_cctor (cfg
->method
->klass
)) && !(cfg
->method
->wrapper_type
== MONO_WRAPPER_NATIVE_TO_MANAGED
)) {
7357 * linkonce methods shouldn't have initialization,
7358 * because they might belong to assemblies which
7359 * haven't been loaded yet.
7361 g_assert (!ctx
->is_linkonce
);
7362 emit_init_method (ctx
);
7364 LLVMBuildBr (ctx
->builder
, ctx
->inited_bb
);
7368 if (cfg
->llvm_only
) {
7369 GHashTableIter iter
;
7371 GSList
*callers
, *l
, *l2
;
7374 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7375 * We can't do this earlier, as it contains llvm instructions which can be
7376 * freed if compilation fails.
7377 * FIXME: Get rid of this when all methods can be llvm compiled.
7379 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
7380 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
7381 for (l
= callers
; l
; l
= l
->next
) {
7382 l2
= (GSList
*)g_hash_table_lookup (ctx
->module
->method_to_callers
, method
);
7383 l2
= g_slist_prepend (l2
, l
->data
);
7384 g_hash_table_insert (ctx
->module
->method_to_callers
, method
, l2
);
7389 if (cfg
->verbose_level
> 1)
7390 mono_llvm_dump_value (method
);
7392 if (cfg
->compile_aot
&& !cfg
->llvm_only
)
7393 mark_as_used (ctx
->module
, method
);
7395 if (!cfg
->llvm_only
) {
7396 LLVMValueRef md_args
[16];
7397 LLVMValueRef md_node
;
7400 if (cfg
->compile_aot
)
7401 method_index
= mono_aot_get_method_index (cfg
->orig_method
);
7404 md_args
[0] = LLVMMDString (ctx
->method_name
, strlen (ctx
->method_name
));
7405 md_args
[1] = LLVMConstInt (LLVMInt32Type (), method_index
, FALSE
);
7406 md_node
= LLVMMDNode (md_args
, 2);
7407 LLVMAddNamedMetadataOperand (lmodule
, "mono.function_indexes", md_node
);
7408 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7411 if (cfg
->compile_aot
) {
7412 /* Don't generate native code, keep the LLVM IR */
7413 if (cfg
->verbose_level
)
7414 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), ctx
->method_name
);
7416 #if LLVM_API_VERSION < 100
7417 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7418 int err
= LLVMVerifyFunction(ctx
->lmethod
, LLVMPrintMessageAction
);
7419 g_assert (err
== 0);
7422 //LLVMVerifyFunction(method, 0);
7423 #if LLVM_API_VERSION > 100
7424 MonoDomain
*domain
= mono_domain_get ();
7425 MonoJitDomainInfo
*domain_info
;
7426 int nvars
= g_hash_table_size (ctx
->jit_callees
);
7427 LLVMValueRef
*callee_vars
= g_new0 (LLVMValueRef
, nvars
);
7428 gpointer
*callee_addrs
= g_new0 (gpointer
, nvars
);
7429 GHashTableIter iter
;
7435 * Compute the addresses of the LLVM globals pointing to the
7436 * methods called by the current method. Pass it to the trampoline
7437 * code so it can update them after their corresponding method was
7440 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7442 while (g_hash_table_iter_next (&iter
, NULL
, (void**)&var
))
7443 callee_vars
[i
++] = var
;
7445 cfg
->native_code
= mono_llvm_compile_method (ctx
->module
->mono_ee
, ctx
->lmethod
, nvars
, callee_vars
, callee_addrs
, &eh_frame
);
7447 decode_llvm_eh_info (ctx
, eh_frame
);
7449 mono_domain_lock (domain
);
7450 domain_info
= domain_jit_info (domain
);
7451 if (!domain_info
->llvm_jit_callees
)
7452 domain_info
->llvm_jit_callees
= g_hash_table_new (NULL
, NULL
);
7453 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7455 while (g_hash_table_iter_next (&iter
, (void**)&callee
, (void**)&var
)) {
7456 GSList
*addrs
= g_hash_table_lookup (domain_info
->llvm_jit_callees
, callee
);
7457 addrs
= g_slist_prepend (addrs
, callee_addrs
[i
]);
7458 g_hash_table_insert (domain_info
->llvm_jit_callees
, callee
, addrs
);
7461 mono_domain_unlock (domain
);
7463 mono_llvm_optimize_method (ctx
->module
->mono_ee
, ctx
->lmethod
);
7465 if (cfg
->verbose_level
> 1)
7466 mono_llvm_dump_value (ctx
->lmethod
);
7468 cfg
->native_code
= (unsigned char*)LLVMGetPointerToGlobal (ctx
->module
->ee
, ctx
->lmethod
);
7470 /* Set by emit_cb */
7471 g_assert (cfg
->code_len
);
7475 if (ctx
->module
->method_to_lmethod
)
7476 g_hash_table_insert (ctx
->module
->method_to_lmethod
, cfg
->method
, ctx
->lmethod
);
7477 if (ctx
->module
->idx_to_lmethod
)
7478 g_hash_table_insert (ctx
->module
->idx_to_lmethod
, GINT_TO_POINTER (cfg
->method_index
), ctx
->lmethod
);
7480 if (ctx
->llvm_only
&& cfg
->orig_method
->klass
->valuetype
&& !(cfg
->orig_method
->flags
& METHOD_ATTRIBUTE_STATIC
))
7481 emit_unbox_tramp (ctx
, ctx
->method_name
, ctx
->method_type
, ctx
->lmethod
, cfg
->method_index
);
7485 * mono_llvm_create_vars:
7487 * Same as mono_arch_create_vars () for LLVM.
7490 mono_llvm_create_vars (MonoCompile
*cfg
)
7492 MonoMethodSignature
*sig
;
7494 sig
= mono_method_signature (cfg
->method
);
7495 if (cfg
->gsharedvt
&& cfg
->llvm_only
) {
7496 if (mini_is_gsharedvt_variable_signature (sig
) && sig
->ret
->type
!= MONO_TYPE_VOID
) {
7497 cfg
->vret_addr
= mono_compile_create_var (cfg
, &mono_get_intptr_class ()->byval_arg
, OP_ARG
);
7498 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
7499 printf ("vret_addr = ");
7500 mono_print_ins (cfg
->vret_addr
);
7504 mono_arch_create_vars (cfg
);
7509 * mono_llvm_emit_call:
7511 * Same as mono_arch_emit_call () for LLVM.
7514 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
7517 MonoMethodSignature
*sig
;
7518 int i
, n
, stack_size
;
7523 sig
= call
->signature
;
7524 n
= sig
->param_count
+ sig
->hasthis
;
7526 call
->cinfo
= get_llvm_call_info (cfg
, sig
);
7528 if (cfg
->disable_llvm
)
7531 if (sig
->call_convention
== MONO_CALL_VARARG
) {
7532 cfg
->exception_message
= g_strdup ("varargs");
7533 cfg
->disable_llvm
= TRUE
;
7536 for (i
= 0; i
< n
; ++i
) {
7539 ainfo
= call
->cinfo
->args
+ i
;
7541 in
= call
->args
[i
];
7543 /* Simply remember the arguments */
7544 switch (ainfo
->storage
) {
7545 case LLVMArgNormal
: {
7546 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? &mono_get_intptr_class ()->byval_arg
: ainfo
->type
;
7549 opcode
= mono_type_to_regmove (cfg
, t
);
7550 if (opcode
== OP_FMOVE
) {
7551 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
7552 ins
->dreg
= mono_alloc_freg (cfg
);
7553 } else if (opcode
== OP_LMOVE
) {
7554 MONO_INST_NEW (cfg
, ins
, OP_LMOVE
);
7555 ins
->dreg
= mono_alloc_lreg (cfg
);
7556 } else if (opcode
== OP_RMOVE
) {
7557 MONO_INST_NEW (cfg
, ins
, OP_RMOVE
);
7558 ins
->dreg
= mono_alloc_freg (cfg
);
7560 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
7561 ins
->dreg
= mono_alloc_ireg (cfg
);
7563 ins
->sreg1
= in
->dreg
;
7566 case LLVMArgVtypeByVal
:
7567 case LLVMArgVtypeByRef
:
7568 case LLVMArgVtypeInReg
:
7569 case LLVMArgVtypeAsScalar
:
7570 case LLVMArgAsIArgs
:
7571 case LLVMArgAsFpArgs
:
7572 case LLVMArgGsharedvtVariable
:
7573 case LLVMArgGsharedvtFixed
:
7574 case LLVMArgGsharedvtFixedVtype
:
7575 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
7576 ins
->dreg
= mono_alloc_ireg (cfg
);
7577 ins
->sreg1
= in
->dreg
;
7578 ins
->inst_p0
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMArgInfo
));
7579 memcpy (ins
->inst_p0
, ainfo
, sizeof (LLVMArgInfo
));
7580 ins
->inst_vtype
= ainfo
->type
;
7581 ins
->klass
= mono_class_from_mono_type (ainfo
->type
);
7584 cfg
->exception_message
= g_strdup ("ainfo->storage");
7585 cfg
->disable_llvm
= TRUE
;
7589 if (!cfg
->disable_llvm
) {
7590 MONO_ADD_INS (cfg
->cbb
, ins
);
7591 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
7596 static unsigned char*
7597 alloc_cb (LLVMValueRef function
, int size
)
7601 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7605 return (unsigned char*)mono_domain_code_reserve (cfg
->domain
, size
);
7607 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size
);
7612 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
7616 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7618 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
7622 exception_cb (void *data
)
7625 MonoJitExceptionInfo
*ei
;
7626 guint32 ei_len
, i
, j
, nested_len
, nindex
;
7627 gpointer
*type_info
;
7628 int this_reg
, this_offset
;
7630 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7634 * data points to a DWARF FDE structure, convert it to our unwind format and
7636 * An alternative would be to save it directly, and modify our unwinder to work
7639 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
);
7640 if (cfg
->verbose_level
> 1)
7641 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7643 /* Count nested clauses */
7645 for (i
= 0; i
< ei_len
; ++i
) {
7646 gint32 cindex1
= *(gint32
*)type_info
[i
];
7647 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7649 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7651 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7653 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7659 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7660 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7661 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7662 /* Fill the rest of the information from the type info */
7663 for (i
= 0; i
< ei_len
; ++i
) {
7664 gint32 clause_index
= *(gint32
*)type_info
[i
];
7665 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7667 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7668 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7669 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7673 * For nested clauses, the LLVM produced exception info associates the try interval with
7674 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7675 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7676 * and everything else from the nested clause.
7679 for (i
= 0; i
< ei_len
; ++i
) {
7680 gint32 cindex1
= *(gint32
*)type_info
[i
];
7681 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7683 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7685 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7686 MonoJitExceptionInfo
*nesting_ei
, *nested_ei
;
7688 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7689 /* clause1 is the nested clause */
7690 nested_ei
= &cfg
->llvm_ex_info
[i
];
7691 nesting_ei
= &cfg
->llvm_ex_info
[nindex
];
7694 memcpy (nesting_ei
, nested_ei
, sizeof (MonoJitExceptionInfo
));
7696 nesting_ei
->flags
= clause2
->flags
;
7697 nesting_ei
->data
.catch_class
= clause2
->data
.catch_class
;
7698 nesting_ei
->clause_index
= cindex2
;
7702 g_assert (nindex
== ei_len
+ nested_len
);
7703 cfg
->llvm_this_reg
= this_reg
;
7704 cfg
->llvm_this_offset
= this_offset
;
7706 /* type_info [i] is cfg mempool allocated, no need to free it */
7712 #if LLVM_API_VERSION > 100
7714 * decode_llvm_eh_info:
7716 * Decode the EH table emitted by llvm in jit mode, and store
7717 * the result into cfg.
7720 decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
)
7722 MonoCompile
*cfg
= ctx
->cfg
;
7725 MonoLLVMFDEInfo info
;
7726 MonoJitExceptionInfo
*ei
;
7727 guint8
*p
= eh_frame
;
7728 int version
, fde_count
, fde_offset
;
7729 guint32 ei_len
, i
, nested_len
;
7730 gpointer
*type_info
;
7734 * Decode the one element EH table emitted by the MonoException class
7738 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7741 g_assert (version
== 3);
7744 p
= (guint8
*)ALIGN_PTR_TO (p
, 4);
7746 fde_count
= *(guint32
*)p
;
7750 g_assert (fde_count
<= 2);
7752 /* The first entry is the real method */
7753 g_assert (table
[0] == 1);
7754 fde_offset
= table
[1];
7755 table
+= fde_count
* 2;
7757 cfg
->code_len
= table
[0];
7758 fde_len
= table
[1] - fde_offset
;
7761 fde
= (guint8
*)eh_frame
+ fde_offset
;
7762 cie
= (guint8
*)table
;
7764 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
);
7766 cfg
->encoded_unwind_ops
= info
.unw_info
;
7767 cfg
->encoded_unwind_ops_len
= info
.unw_info_len
;
7768 if (cfg
->verbose_level
> 1)
7769 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7770 if (info
.this_reg
!= -1) {
7771 cfg
->llvm_this_reg
= info
.this_reg
;
7772 cfg
->llvm_this_offset
= info
.this_offset
;
7776 ei_len
= info
.ex_info_len
;
7777 type_info
= info
.type_info
;
7779 // Nested clauses are currently disabled
7782 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7783 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7784 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7785 /* Fill the rest of the information from the type info */
7786 for (i
= 0; i
< ei_len
; ++i
) {
7787 gint32 clause_index
= *(gint32
*)type_info
[i
];
7788 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7790 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7791 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7792 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7798 dlsym_cb (const char *name
, void **symbol
)
7804 if (!strcmp (name
, "__bzero")) {
7805 *symbol
= (void*)bzero
;
7807 current
= mono_dl_open (NULL
, 0, NULL
);
7810 err
= mono_dl_symbol (current
, name
, symbol
);
7812 mono_dl_close (current
);
7814 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7815 *symbol
= (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8
*)(*symbol
));
7821 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
7823 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
7827 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
7829 LLVMTypeRef param_types
[4];
7831 param_types
[0] = param_type1
;
7832 param_types
[1] = param_type2
;
7834 AddFunc (module
, name
, ret_type
, param_types
, 2);
7840 INTRINS_SADD_OVF_I32
,
7841 INTRINS_UADD_OVF_I32
,
7842 INTRINS_SSUB_OVF_I32
,
7843 INTRINS_USUB_OVF_I32
,
7844 INTRINS_SMUL_OVF_I32
,
7845 INTRINS_UMUL_OVF_I32
,
7846 INTRINS_SADD_OVF_I64
,
7847 INTRINS_UADD_OVF_I64
,
7848 INTRINS_SSUB_OVF_I64
,
7849 INTRINS_USUB_OVF_I64
,
7850 INTRINS_SMUL_OVF_I64
,
7851 INTRINS_UMUL_OVF_I64
,
7858 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7859 INTRINS_SSE_PMOVMSKB
,
7860 INTRINS_SSE_PSRLI_W
,
7861 INTRINS_SSE_PSRAI_W
,
7862 INTRINS_SSE_PSLLI_W
,
7863 INTRINS_SSE_PSRLI_D
,
7864 INTRINS_SSE_PSRAI_D
,
7865 INTRINS_SSE_PSLLI_D
,
7866 INTRINS_SSE_PSRLI_Q
,
7867 INTRINS_SSE_PSLLI_Q
,
7868 INTRINS_SSE_SQRT_PD
,
7869 INTRINS_SSE_SQRT_PS
,
7870 INTRINS_SSE_RSQRT_PS
,
7872 INTRINS_SSE_CVTTPD2DQ
,
7873 INTRINS_SSE_CVTTPS2DQ
,
7874 INTRINS_SSE_CVTDQ2PD
,
7875 INTRINS_SSE_CVTDQ2PS
,
7876 INTRINS_SSE_CVTPD2DQ
,
7877 INTRINS_SSE_CVTPS2DQ
,
7878 INTRINS_SSE_CVTPD2PS
,
7879 INTRINS_SSE_CVTPS2PD
,
7882 INTRINS_SSE_PACKSSWB
,
7883 INTRINS_SSE_PACKUSWB
,
7884 INTRINS_SSE_PACKSSDW
,
7885 INTRINS_SSE_PACKUSDW
,
7890 INTRINS_SSE_ADDSUBPS
,
7895 INTRINS_SSE_ADDSUBPD
,
7898 INTRINS_SSE_PADDUSW
,
7899 INTRINS_SSE_PSUBUSW
,
7905 INTRINS_SSE_PADDUSB
,
7906 INTRINS_SSE_PSUBUSB
,
7919 static IntrinsicDesc intrinsics
[] = {
7920 {INTRINS_MEMSET
, "llvm.memset.p0i8.i32"},
7921 {INTRINS_MEMCPY
, "llvm.memcpy.p0i8.p0i8.i32"},
7922 {INTRINS_SADD_OVF_I32
, "llvm.sadd.with.overflow.i32"},
7923 {INTRINS_UADD_OVF_I32
, "llvm.uadd.with.overflow.i32"},
7924 {INTRINS_SSUB_OVF_I32
, "llvm.ssub.with.overflow.i32"},
7925 {INTRINS_USUB_OVF_I32
, "llvm.usub.with.overflow.i32"},
7926 {INTRINS_SMUL_OVF_I32
, "llvm.smul.with.overflow.i32"},
7927 {INTRINS_UMUL_OVF_I32
, "llvm.umul.with.overflow.i32"},
7928 {INTRINS_SADD_OVF_I64
, "llvm.sadd.with.overflow.i64"},
7929 {INTRINS_UADD_OVF_I64
, "llvm.uadd.with.overflow.i64"},
7930 {INTRINS_SSUB_OVF_I64
, "llvm.ssub.with.overflow.i64"},
7931 {INTRINS_USUB_OVF_I64
, "llvm.usub.with.overflow.i64"},
7932 {INTRINS_SMUL_OVF_I64
, "llvm.smul.with.overflow.i64"},
7933 {INTRINS_UMUL_OVF_I64
, "llvm.umul.with.overflow.i64"},
7934 {INTRINS_SIN
, "llvm.sin.f64"},
7935 {INTRINS_COS
, "llvm.cos.f64"},
7936 {INTRINS_SQRT
, "llvm.sqrt.f64"},
7937 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7938 {INTRINS_FABS
, "fabs"},
7939 {INTRINS_EXPECT_I8
, "llvm.expect.i8"},
7940 {INTRINS_EXPECT_I1
, "llvm.expect.i1"},
7941 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7942 {INTRINS_SSE_PMOVMSKB
, "llvm.x86.sse2.pmovmskb.128"},
7943 {INTRINS_SSE_PSRLI_W
, "llvm.x86.sse2.psrli.w"},
7944 {INTRINS_SSE_PSRAI_W
, "llvm.x86.sse2.psrai.w"},
7945 {INTRINS_SSE_PSLLI_W
, "llvm.x86.sse2.pslli.w"},
7946 {INTRINS_SSE_PSRLI_D
, "llvm.x86.sse2.psrli.d"},
7947 {INTRINS_SSE_PSRAI_D
, "llvm.x86.sse2.psrai.d"},
7948 {INTRINS_SSE_PSLLI_D
, "llvm.x86.sse2.pslli.d"},
7949 {INTRINS_SSE_PSRLI_Q
, "llvm.x86.sse2.psrli.q"},
7950 {INTRINS_SSE_PSLLI_Q
, "llvm.x86.sse2.pslli.q"},
7951 {INTRINS_SSE_SQRT_PD
, "llvm.x86.sse2.sqrt.pd"},
7952 {INTRINS_SSE_SQRT_PS
, "llvm.x86.sse.sqrt.ps"},
7953 {INTRINS_SSE_RSQRT_PS
, "llvm.x86.sse.rsqrt.ps"},
7954 {INTRINS_SSE_RCP_PS
, "llvm.x86.sse.rcp.ps"},
7955 {INTRINS_SSE_CVTTPD2DQ
, "llvm.x86.sse2.cvttpd2dq"},
7956 {INTRINS_SSE_CVTTPS2DQ
, "llvm.x86.sse2.cvttps2dq"},
7957 {INTRINS_SSE_CVTDQ2PD
, "llvm.x86.sse2.cvtdq2pd"},
7958 {INTRINS_SSE_CVTDQ2PS
, "llvm.x86.sse2.cvtdq2ps"},
7959 {INTRINS_SSE_CVTPD2DQ
, "llvm.x86.sse2.cvtpd2dq"},
7960 {INTRINS_SSE_CVTPS2DQ
, "llvm.x86.sse2.cvtps2dq"},
7961 {INTRINS_SSE_CVTPD2PS
, "llvm.x86.sse2.cvtpd2ps"},
7962 {INTRINS_SSE_CVTPS2PD
, "llvm.x86.sse2.cvtps2pd"},
7963 {INTRINS_SSE_CMPPD
, "llvm.x86.sse2.cmp.pd"},
7964 {INTRINS_SSE_CMPPS
, "llvm.x86.sse.cmp.ps"},
7965 {INTRINS_SSE_PACKSSWB
, "llvm.x86.sse2.packsswb.128"},
7966 {INTRINS_SSE_PACKUSWB
, "llvm.x86.sse2.packuswb.128"},
7967 {INTRINS_SSE_PACKSSDW
, "llvm.x86.sse2.packssdw.128"},
7968 {INTRINS_SSE_PACKUSDW
, "llvm.x86.sse41.packusdw"},
7969 {INTRINS_SSE_MINPS
, "llvm.x86.sse.min.ps"},
7970 {INTRINS_SSE_MAXPS
, "llvm.x86.sse.max.ps"},
7971 {INTRINS_SSE_HADDPS
, "llvm.x86.sse3.hadd.ps"},
7972 {INTRINS_SSE_HSUBPS
, "llvm.x86.sse3.hsub.ps"},
7973 {INTRINS_SSE_ADDSUBPS
, "llvm.x86.sse3.addsub.ps"},
7974 {INTRINS_SSE_MINPD
, "llvm.x86.sse2.min.pd"},
7975 {INTRINS_SSE_MAXPD
, "llvm.x86.sse2.max.pd"},
7976 {INTRINS_SSE_HADDPD
, "llvm.x86.sse3.hadd.pd"},
7977 {INTRINS_SSE_HSUBPD
, "llvm.x86.sse3.hsub.pd"},
7978 {INTRINS_SSE_ADDSUBPD
, "llvm.x86.sse3.addsub.pd"},
7979 {INTRINS_SSE_PADDSW
, "llvm.x86.sse2.padds.w"},
7980 {INTRINS_SSE_PSUBSW
, "llvm.x86.sse2.psubs.w"},
7981 {INTRINS_SSE_PADDUSW
, "llvm.x86.sse2.paddus.w"},
7982 {INTRINS_SSE_PSUBUSW
, "llvm.x86.sse2.psubus.w"},
7983 {INTRINS_SSE_PAVGW
, "llvm.x86.sse2.pavg.w"},
7984 {INTRINS_SSE_PMULHW
, "llvm.x86.sse2.pmulh.w"},
7985 {INTRINS_SSE_PMULHU
, "llvm.x86.sse2.pmulhu.w"},
7986 {INTRINS_SE_PADDSB
, "llvm.x86.sse2.padds.b"},
7987 {INTRINS_SSE_PSUBSB
, "llvm.x86.sse2.psubs.b"},
7988 {INTRINS_SSE_PADDUSB
, "llvm.x86.sse2.paddus.b"},
7989 {INTRINS_SSE_PSUBUSB
, "llvm.x86.sse2.psubus.b"},
7990 {INTRINS_SSE_PAVGB
, "llvm.x86.sse2.pavg.b"},
7991 {INTRINS_SSE_PAUSE
, "llvm.x86.sse2.pause"},
7992 {INTRINS_SSE_DPPS
, "llvm.x86.sse41.dpps"}
7997 add_sse_binary (LLVMModuleRef module
, const char *name
, int type
)
7999 LLVMTypeRef ret_type
= type_to_simd_type (type
);
8000 AddFunc2 (module
, name
, ret_type
, ret_type
, ret_type
);
8004 add_intrinsic (LLVMModuleRef module
, int id
)
8007 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8008 LLVMTypeRef ret_type
, arg_types
[16];
8011 name
= g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
8015 case INTRINS_MEMSET
: {
8016 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8018 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8021 case INTRINS_MEMCPY
: {
8022 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8024 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
8027 case INTRINS_SADD_OVF_I32
:
8028 case INTRINS_UADD_OVF_I32
:
8029 case INTRINS_SSUB_OVF_I32
:
8030 case INTRINS_USUB_OVF_I32
:
8031 case INTRINS_SMUL_OVF_I32
:
8032 case INTRINS_UMUL_OVF_I32
: {
8033 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
8034 LLVMTypeRef params
[] = { LLVMInt32Type (), LLVMInt32Type () };
8035 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i32
, 2, FALSE
);
8037 AddFunc (module
, name
, ret_type
, params
, 2);
8040 case INTRINS_SADD_OVF_I64
:
8041 case INTRINS_UADD_OVF_I64
:
8042 case INTRINS_SSUB_OVF_I64
:
8043 case INTRINS_USUB_OVF_I64
:
8044 case INTRINS_SMUL_OVF_I64
:
8045 case INTRINS_UMUL_OVF_I64
: {
8046 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
8047 LLVMTypeRef params
[] = { LLVMInt64Type (), LLVMInt64Type () };
8048 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i64
, 2, FALSE
);
8050 AddFunc (module
, name
, ret_type
, params
, 2);
8056 case INTRINS_FABS
: {
8057 LLVMTypeRef params
[] = { LLVMDoubleType () };
8059 AddFunc (module
, name
, LLVMDoubleType (), params
, 1);
8062 case INTRINS_EXPECT_I8
:
8063 AddFunc2 (module
, name
, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8065 case INTRINS_EXPECT_I1
:
8066 AddFunc2 (module
, name
, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8068 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8069 case INTRINS_SSE_PMOVMSKB
:
8071 ret_type
= LLVMInt32Type ();
8072 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
8073 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8075 case INTRINS_SSE_PSRLI_W
:
8076 case INTRINS_SSE_PSRAI_W
:
8077 case INTRINS_SSE_PSLLI_W
:
8079 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8080 arg_types
[0] = ret_type
;
8081 arg_types
[1] = LLVMInt32Type ();
8082 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8084 case INTRINS_SSE_PSRLI_D
:
8085 case INTRINS_SSE_PSRAI_D
:
8086 case INTRINS_SSE_PSLLI_D
:
8087 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8088 arg_types
[0] = ret_type
;
8089 arg_types
[1] = LLVMInt32Type ();
8090 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8092 case INTRINS_SSE_PSRLI_Q
:
8093 case INTRINS_SSE_PSLLI_Q
:
8094 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
8095 arg_types
[0] = ret_type
;
8096 arg_types
[1] = LLVMInt32Type ();
8097 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8099 case INTRINS_SSE_SQRT_PD
:
8101 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8102 arg_types
[0] = ret_type
;
8103 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8105 case INTRINS_SSE_SQRT_PS
:
8106 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8107 arg_types
[0] = ret_type
;
8108 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8110 case INTRINS_SSE_RSQRT_PS
:
8111 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8112 arg_types
[0] = ret_type
;
8113 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8115 case INTRINS_SSE_RCP_PS
:
8116 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8117 arg_types
[0] = ret_type
;
8118 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8120 case INTRINS_SSE_CVTTPD2DQ
:
8121 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8122 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8123 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8125 case INTRINS_SSE_CVTTPS2DQ
:
8126 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8127 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8128 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8130 case INTRINS_SSE_CVTDQ2PD
:
8131 /* Conversion ops */
8132 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8133 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8134 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8136 case INTRINS_SSE_CVTDQ2PS
:
8137 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8138 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8139 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8141 case INTRINS_SSE_CVTPD2DQ
:
8142 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8143 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8144 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8146 case INTRINS_SSE_CVTPS2DQ
:
8147 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
8148 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8149 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8151 case INTRINS_SSE_CVTPD2PS
:
8152 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8153 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8154 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8156 case INTRINS_SSE_CVTPS2PD
:
8157 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8158 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8159 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8161 case INTRINS_SSE_CMPPD
:
8163 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8164 arg_types
[0] = ret_type
;
8165 arg_types
[1] = ret_type
;
8166 arg_types
[2] = LLVMInt8Type ();
8167 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8169 case INTRINS_SSE_CMPPS
:
8170 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8171 arg_types
[0] = ret_type
;
8172 arg_types
[1] = ret_type
;
8173 arg_types
[2] = LLVMInt8Type ();
8174 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8176 case INTRINS_SSE_PACKSSWB
:
8177 case INTRINS_SSE_PACKUSWB
:
8178 case INTRINS_SSE_PACKSSDW
:
8180 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
8181 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
8182 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
8183 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8185 case INTRINS_SSE_PACKUSDW
:
8186 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8187 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8188 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
8189 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8191 /* SSE Binary ops */
8192 case INTRINS_SSE_PADDSW
:
8193 case INTRINS_SSE_PSUBSW
:
8194 case INTRINS_SSE_PADDUSW
:
8195 case INTRINS_SSE_PSUBUSW
:
8196 case INTRINS_SSE_PAVGW
:
8197 case INTRINS_SSE_PMULHW
:
8198 case INTRINS_SSE_PMULHU
:
8199 add_sse_binary (module
, name
, MONO_TYPE_I2
);
8201 case INTRINS_SSE_MINPS
:
8202 case INTRINS_SSE_MAXPS
:
8203 case INTRINS_SSE_HADDPS
:
8204 case INTRINS_SSE_HSUBPS
:
8205 case INTRINS_SSE_ADDSUBPS
:
8206 add_sse_binary (module
, name
, MONO_TYPE_R4
);
8208 case INTRINS_SSE_MINPD
:
8209 case INTRINS_SSE_MAXPD
:
8210 case INTRINS_SSE_HADDPD
:
8211 case INTRINS_SSE_HSUBPD
:
8212 case INTRINS_SSE_ADDSUBPD
:
8213 add_sse_binary (module
, name
, MONO_TYPE_R8
);
8215 case INTRINS_SE_PADDSB
:
8216 case INTRINS_SSE_PSUBSB
:
8217 case INTRINS_SSE_PADDUSB
:
8218 case INTRINS_SSE_PSUBUSB
:
8219 case INTRINS_SSE_PAVGB
:
8220 add_sse_binary (module
, name
, MONO_TYPE_I1
);
8222 case INTRINS_SSE_PAUSE
:
8223 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
8225 case INTRINS_SSE_DPPS
:
8226 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8227 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8228 arg_types
[1] = type_to_simd_type (MONO_TYPE_R4
);
8229 arg_types
[2] = LLVMInt32Type ();
8230 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8234 g_assert_not_reached ();
8240 get_intrinsic (EmitContext
*ctx
, const char *name
)
8242 #if LLVM_API_VERSION > 100
8246 * Every method is emitted into its own module so
8247 * we can add intrinsics on demand.
8249 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8253 /* No locking needed */
8254 id
= GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id
, name
));
8257 printf ("%s\n", name
);
8258 g_assert (id
!= -1);
8259 add_intrinsic (ctx
->lmodule
, id
);
8260 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8268 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8275 add_intrinsics (LLVMModuleRef module
)
8279 /* Emit declarations of instrinsics */
8281 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8282 * type doesn't seem to do any locking.
8284 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8285 add_intrinsic (module
, i
);
8289 AddFunc (module
, "mono_personality", LLVMVoidType (), NULL
, 0);
8291 AddFunc (module
, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL
, 0);
8294 /* Load/Store intrinsics */
8296 LLVMTypeRef arg_types
[5];
8300 for (i
= 1; i
<= 8; i
*= 2) {
8301 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8302 arg_types
[1] = LLVMInt32Type ();
8303 arg_types
[2] = LLVMInt1Type ();
8304 arg_types
[3] = LLVMInt32Type ();
8305 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
8306 AddFunc (module
, name
, LLVMIntType (i
* 8), arg_types
, 4);
8308 arg_types
[0] = LLVMIntType (i
* 8);
8309 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8310 arg_types
[2] = LLVMInt32Type ();
8311 arg_types
[3] = LLVMInt1Type ();
8312 arg_types
[4] = LLVMInt32Type ();
8313 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
8314 AddFunc (module
, name
, LLVMVoidType (), arg_types
, 5);
8320 add_types (MonoLLVMModule
*module
)
8322 module
->ptr_type
= LLVMPointerType (sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8326 mono_llvm_init (void)
8331 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
8333 h
= g_hash_table_new (NULL
, NULL
);
8334 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8335 g_hash_table_insert (h
, GINT_TO_POINTER (intrinsics
[i
].id
), (gpointer
)intrinsics
[i
].name
);
8336 intrins_id_to_name
= h
;
8338 h
= g_hash_table_new (g_str_hash
, g_str_equal
);
8339 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8340 g_hash_table_insert (h
, (gpointer
)intrinsics
[i
].name
, GINT_TO_POINTER (intrinsics
[i
].id
+ 1));
8341 intrins_name_to_id
= h
;
8345 init_jit_module (MonoDomain
*domain
)
8347 MonoJitDomainInfo
*dinfo
;
8348 MonoLLVMModule
*module
;
8351 dinfo
= domain_jit_info (domain
);
8352 if (dinfo
->llvm_module
)
8355 mono_loader_lock ();
8357 if (dinfo
->llvm_module
) {
8358 mono_loader_unlock ();
8362 module
= g_new0 (MonoLLVMModule
, 1);
8364 name
= g_strdup_printf ("mono-%s", domain
->friendly_name
);
8365 module
->lmodule
= LLVMModuleCreateWithName (name
);
8366 module
->context
= LLVMGetGlobalContext ();
8368 module
->mono_ee
= (MonoEERef
*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module
->lmodule
), alloc_cb
, emitted_cb
, exception_cb
, dlsym_cb
, &module
->ee
);
8370 add_intrinsics (module
->lmodule
);
8373 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8375 #if LLVM_API_VERSION < 100
8376 MonoJitICallInfo
*info
;
8378 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8380 LLVMAddGlobalMapping (module
->ee
, LLVMGetNamedFunction (module
->lmodule
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
8383 mono_memory_barrier ();
8385 dinfo
->llvm_module
= module
;
8387 mono_loader_unlock ();
8391 mono_llvm_cleanup (void)
8393 MonoLLVMModule
*module
= &aot_module
;
8395 if (module
->lmodule
)
8396 LLVMDisposeModule (module
->lmodule
);
8398 if (module
->context
)
8399 LLVMContextDispose (module
->context
);
8403 mono_llvm_free_domain_info (MonoDomain
*domain
)
8405 MonoJitDomainInfo
*info
= domain_jit_info (domain
);
8406 MonoLLVMModule
*module
= (MonoLLVMModule
*)info
->llvm_module
;
8412 if (module
->llvm_types
)
8413 g_hash_table_destroy (module
->llvm_types
);
8415 mono_llvm_dispose_ee (module
->mono_ee
);
8417 if (module
->bb_names
) {
8418 for (i
= 0; i
< module
->bb_names_len
; ++i
)
8419 g_free (module
->bb_names
[i
]);
8420 g_free (module
->bb_names
);
8422 //LLVMDisposeModule (module->module);
8426 info
->llvm_module
= NULL
;
8430 mono_llvm_create_aot_module (MonoAssembly
*assembly
, const char *global_prefix
, gboolean emit_dwarf
, gboolean static_link
, gboolean llvm_only
)
8432 MonoLLVMModule
*module
= &aot_module
;
8434 /* Delete previous module */
8435 if (module
->plt_entries
)
8436 g_hash_table_destroy (module
->plt_entries
);
8437 if (module
->lmodule
)
8438 LLVMDisposeModule (module
->lmodule
);
8440 memset (module
, 0, sizeof (aot_module
));
8442 module
->lmodule
= LLVMModuleCreateWithName ("aot");
8443 module
->assembly
= assembly
;
8444 module
->global_prefix
= g_strdup (global_prefix
);
8445 module
->got_symbol
= g_strdup_printf ("%s_llvm_got", global_prefix
);
8446 module
->eh_frame_symbol
= g_strdup_printf ("%s_eh_frame", global_prefix
);
8447 module
->get_method_symbol
= g_strdup_printf ("%s_get_method", global_prefix
);
8448 module
->get_unbox_tramp_symbol
= g_strdup_printf ("%s_get_unbox_tramp", global_prefix
);
8449 module
->external_symbols
= TRUE
;
8450 module
->emit_dwarf
= emit_dwarf
;
8451 module
->static_link
= static_link
;
8452 module
->llvm_only
= llvm_only
;
8453 /* The first few entries are reserved */
8454 module
->max_got_offset
= 16;
8455 module
->context
= LLVMGetGlobalContext ();
8458 /* clang ignores our debug info because it has an invalid version */
8459 module
->emit_dwarf
= FALSE
;
8461 add_intrinsics (module
->lmodule
);
8464 #if LLVM_API_VERSION > 100
8465 if (module
->emit_dwarf
) {
8466 char *dir
, *build_info
, *s
, *cu_name
;
8468 module
->di_builder
= mono_llvm_create_di_builder (module
->lmodule
);
8471 dir
= g_strdup (".");
8472 build_info
= mono_get_runtime_build_info ();
8473 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8474 cu_name
= g_path_get_basename (assembly
->image
->name
);
8475 module
->cu
= mono_llvm_di_create_compile_unit (module
->di_builder
, cu_name
, dir
, s
);
8477 g_free (build_info
);
8484 * We couldn't compute the type of the LLVM global representing the got because
8485 * its size is only known after all the methods have been emitted. So create
8486 * a dummy variable, and replace all uses it with the real got variable when
8487 * its size is known in mono_llvm_emit_aot_module ().
8490 LLVMTypeRef got_type
= LLVMArrayType (module
->ptr_type
, 0);
8492 module
->got_var
= LLVMAddGlobal (module
->lmodule
, got_type
, "mono_dummy_got");
8493 LLVMSetInitializer (module
->got_var
, LLVMConstNull (got_type
));
8496 /* Add initialization array */
8498 LLVMTypeRef inited_type
= LLVMArrayType (LLVMInt8Type (), 0);
8500 module
->inited_var
= LLVMAddGlobal (aot_module
.lmodule
, inited_type
, "mono_inited_tmp");
8501 LLVMSetInitializer (module
->inited_var
, LLVMConstNull (inited_type
));
8505 emit_init_icall_wrappers (module
);
8507 emit_llvm_code_start (module
);
8509 /* Add a dummy personality function */
8510 if (!use_debug_personality
) {
8511 LLVMValueRef personality
= LLVMAddFunction (module
->lmodule
, default_personality_name
, LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
));
8512 LLVMSetLinkage (personality
, LLVMExternalLinkage
);
8513 mark_as_used (module
, personality
);
8516 /* Add a reference to the c++ exception we throw/catch */
8518 LLVMTypeRef exc
= LLVMPointerType (LLVMInt8Type (), 0);
8519 module
->sentinel_exception
= LLVMAddGlobal (module
->lmodule
, exc
, "_ZTIPi");
8520 LLVMSetLinkage (module
->sentinel_exception
, LLVMExternalLinkage
);
8521 mono_llvm_set_is_constant (module
->sentinel_exception
);
8524 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8525 module
->plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
8526 module
->plt_entries_ji
= g_hash_table_new (NULL
, NULL
);
8527 module
->direct_callables
= g_hash_table_new (g_str_hash
, g_str_equal
);
8528 module
->method_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8529 module
->idx_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8530 module
->idx_to_unbox_tramp
= g_hash_table_new (NULL
, NULL
);
8531 module
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
8535 llvm_array_from_uints (LLVMTypeRef el_type
, guint32
*values
, int nvalues
)
8538 LLVMValueRef res
, *vals
;
8540 vals
= g_new0 (LLVMValueRef
, nvalues
);
8541 for (i
= 0; i
< nvalues
; ++i
)
8542 vals
[i
] = LLVMConstInt (LLVMInt32Type (), values
[i
], FALSE
);
8543 res
= LLVMConstArray (LLVMInt32Type (), vals
, nvalues
);
8549 llvm_array_from_bytes (guint8
*values
, int nvalues
)
8552 LLVMValueRef res
, *vals
;
8554 vals
= g_new0 (LLVMValueRef
, nvalues
);
8555 for (i
= 0; i
< nvalues
; ++i
)
8556 vals
[i
] = LLVMConstInt (LLVMInt8Type (), values
[i
], FALSE
);
8557 res
= LLVMConstArray (LLVMInt8Type (), vals
, nvalues
);
8562 * mono_llvm_emit_aot_file_info:
8564 * Emit the MonoAotFileInfo structure.
8565 * Same as emit_aot_file_info () in aot-compiler.c.
8568 mono_llvm_emit_aot_file_info (MonoAotFileInfo
*info
, gboolean has_jitted_code
)
8570 MonoLLVMModule
*module
= &aot_module
;
8572 /* Save these for later */
8573 memcpy (&module
->aot_info
, info
, sizeof (MonoAotFileInfo
));
8574 module
->has_jitted_code
= has_jitted_code
;
8578 * mono_llvm_emit_aot_data:
8580 * Emit the binary data DATA pointed to by symbol SYMBOL.
8583 mono_llvm_emit_aot_data (const char *symbol
, guint8
*data
, int data_len
)
8585 MonoLLVMModule
*module
= &aot_module
;
8589 type
= LLVMArrayType (LLVMInt8Type (), data_len
);
8590 d
= LLVMAddGlobal (module
->lmodule
, type
, symbol
);
8591 LLVMSetVisibility (d
, LLVMHiddenVisibility
);
8592 LLVMSetLinkage (d
, LLVMInternalLinkage
);
8593 LLVMSetInitializer (d
, mono_llvm_create_constant_data_array (data
, data_len
));
8594 mono_llvm_set_is_constant (d
);
8597 /* Add a reference to a global defined in JITted code */
8599 AddJitGlobal (MonoLLVMModule
*module
, LLVMTypeRef type
, const char *name
)
8604 s
= g_strdup_printf ("%s%s", module
->global_prefix
, name
);
8605 v
= LLVMAddGlobal (module
->lmodule
, LLVMInt8Type (), s
);
8611 emit_aot_file_info (MonoLLVMModule
*module
)
8613 LLVMTypeRef file_info_type
;
8614 LLVMTypeRef
*eltypes
, eltype
;
8615 LLVMValueRef info_var
;
8616 LLVMValueRef
*fields
;
8617 int i
, nfields
, tindex
;
8618 MonoAotFileInfo
*info
;
8619 LLVMModuleRef lmodule
= module
->lmodule
;
8621 info
= &module
->aot_info
;
8623 /* Create an LLVM type to represent MonoAotFileInfo */
8624 nfields
= 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS
+ 16 + 5;
8625 eltypes
= g_new (LLVMTypeRef
, nfields
);
8627 eltypes
[tindex
++] = LLVMInt32Type ();
8628 eltypes
[tindex
++] = LLVMInt32Type ();
8630 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8631 eltypes
[tindex
++] = LLVMPointerType (LLVMInt8Type (), 0);
8633 for (i
= 0; i
< 15; ++i
)
8634 eltypes
[tindex
++] = LLVMInt32Type ();
8636 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM
);
8637 for (i
= 0; i
< 4; ++i
)
8638 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM
);
8639 eltypes
[tindex
++] = LLVMArrayType (LLVMInt8Type (), 16);
8640 g_assert (tindex
== nfields
);
8641 file_info_type
= LLVMStructCreateNamed (module
->context
, "MonoAotFileInfo");
8642 LLVMStructSetBody (file_info_type
, eltypes
, nfields
, FALSE
);
8644 info_var
= LLVMAddGlobal (lmodule
, file_info_type
, "mono_aot_file_info");
8645 if (module
->static_link
) {
8646 LLVMSetVisibility (info_var
, LLVMHiddenVisibility
);
8647 LLVMSetLinkage (info_var
, LLVMInternalLinkage
);
8649 fields
= g_new (LLVMValueRef
, nfields
);
8651 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->version
, FALSE
);
8652 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->dummy
, FALSE
);
8656 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8657 * for symbols defined in the .s file emitted by the aot compiler.
8659 eltype
= eltypes
[tindex
];
8660 if (module
->llvm_only
)
8661 fields
[tindex
++] = LLVMConstNull (eltype
);
8663 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_got");
8664 fields
[tindex
++] = module
->got_var
;
8665 /* llc defines this directly */
8666 if (!module
->llvm_only
) {
8667 fields
[tindex
++] = LLVMAddGlobal (lmodule
, eltype
, module
->eh_frame_symbol
);
8668 fields
[tindex
++] = LLVMConstNull (eltype
);
8669 fields
[tindex
++] = LLVMConstNull (eltype
);
8671 fields
[tindex
++] = LLVMConstNull (eltype
);
8672 fields
[tindex
++] = module
->get_method
;
8673 fields
[tindex
++] = module
->get_unbox_tramp
;
8675 if (module
->has_jitted_code
) {
8676 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_start");
8677 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_end");
8679 fields
[tindex
++] = LLVMConstNull (eltype
);
8680 fields
[tindex
++] = LLVMConstNull (eltype
);
8682 if (!module
->llvm_only
)
8683 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "method_addresses");
8685 fields
[tindex
++] = LLVMConstNull (eltype
);
8686 if (info
->flags
& MONO_AOT_FILE_FLAG_SEPARATE_DATA
) {
8687 for (i
= 0; i
< MONO_AOT_TABLE_NUM
; ++i
)
8688 fields
[tindex
++] = LLVMConstNull (eltype
);
8690 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "blob");
8691 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_name_table");
8692 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_info_offsets");
8693 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "method_info_offsets");
8694 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "ex_info_offsets");
8695 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_info_offsets");
8696 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_table");
8697 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "got_info_offsets");
8698 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "llvm_got_info_offsets");
8699 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "image_table");
8701 /* Not needed (mem_end) */
8702 fields
[tindex
++] = LLVMConstNull (eltype
);
8703 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_guid");
8704 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "runtime_version");
8705 if (info
->trampoline_size
[0]) {
8706 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "specific_trampolines");
8707 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "static_rgctx_trampolines");
8708 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "imt_trampolines");
8709 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "gsharedvt_arg_trampolines");
8711 fields
[tindex
++] = LLVMConstNull (eltype
);
8712 fields
[tindex
++] = LLVMConstNull (eltype
);
8713 fields
[tindex
++] = LLVMConstNull (eltype
);
8714 fields
[tindex
++] = LLVMConstNull (eltype
);
8716 if (module
->static_link
&& !module
->llvm_only
)
8717 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "globals");
8719 fields
[tindex
++] = LLVMConstNull (eltype
);
8720 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_name");
8721 if (!module
->llvm_only
) {
8722 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt");
8723 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt_end");
8724 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unwind_info");
8725 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines");
8726 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines_end");
8727 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampoline_addresses");
8729 fields
[tindex
++] = LLVMConstNull (eltype
);
8730 fields
[tindex
++] = LLVMConstNull (eltype
);
8731 fields
[tindex
++] = LLVMConstNull (eltype
);
8732 fields
[tindex
++] = LLVMConstNull (eltype
);
8733 fields
[tindex
++] = LLVMConstNull (eltype
);
8734 fields
[tindex
++] = LLVMConstNull (eltype
);
8737 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8738 fields
[2 + i
] = LLVMConstBitCast (fields
[2 + i
], eltype
);
8741 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_got_offset_base
, FALSE
);
8742 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->got_size
, FALSE
);
8743 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_size
, FALSE
);
8744 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nmethods
, FALSE
);
8745 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->flags
, FALSE
);
8746 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->opts
, FALSE
);
8747 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->simd_opts
, FALSE
);
8748 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->gc_name_index
, FALSE
);
8749 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->num_rgctx_fetch_trampolines
, FALSE
);
8750 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->double_align
, FALSE
);
8751 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->long_align
, FALSE
);
8752 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->generic_tramp_num
, FALSE
);
8753 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->tramp_page_size
, FALSE
);
8754 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nshared_got_entries
, FALSE
);
8755 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->datafile_size
, FALSE
);
8757 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->table_offsets
, MONO_AOT_TABLE_NUM
);
8758 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->num_trampolines
, MONO_AOT_TRAMP_NUM
);
8759 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_got_offset_base
, MONO_AOT_TRAMP_NUM
);
8760 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_size
, MONO_AOT_TRAMP_NUM
);
8761 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->tramp_page_code_offsets
, MONO_AOT_TRAMP_NUM
);
8763 fields
[tindex
++] = llvm_array_from_bytes (info
->aotid
, 16);
8764 g_assert (tindex
== nfields
);
8766 LLVMSetInitializer (info_var
, LLVMConstNamedStruct (file_info_type
, fields
, nfields
));
8768 if (module
->static_link
) {
8772 s
= g_strdup_printf ("mono_aot_module_%s_info", module
->assembly
->aname
.name
);
8773 /* Get rid of characters which cannot occur in symbols */
8775 for (p
= s
; *p
; ++p
) {
8776 if (!(isalnum (*p
) || *p
== '_'))
8779 var
= LLVMAddGlobal (module
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), s
);
8781 LLVMSetInitializer (var
, LLVMConstBitCast (LLVMGetNamedGlobal (module
->lmodule
, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8782 LLVMSetLinkage (var
, LLVMExternalLinkage
);
8787 * Emit the aot module into the LLVM bitcode file FILENAME.
8790 mono_llvm_emit_aot_module (const char *filename
, const char *cu_name
)
8792 LLVMTypeRef got_type
, inited_type
;
8793 LLVMValueRef real_got
, real_inited
;
8794 MonoLLVMModule
*module
= &aot_module
;
8796 emit_llvm_code_end (module
);
8799 * Create the real got variable and replace all uses of the dummy variable with
8802 got_type
= LLVMArrayType (module
->ptr_type
, module
->max_got_offset
+ 1);
8803 real_got
= LLVMAddGlobal (module
->lmodule
, got_type
, module
->got_symbol
);
8804 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
8805 if (module
->external_symbols
) {
8806 LLVMSetLinkage (real_got
, LLVMExternalLinkage
);
8807 LLVMSetVisibility (real_got
, LLVMHiddenVisibility
);
8809 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
8811 mono_llvm_replace_uses_of (module
->got_var
, real_got
);
8813 mark_as_used (&aot_module
, real_got
);
8815 /* Delete the dummy got so it doesn't become a global */
8816 LLVMDeleteGlobal (module
->got_var
);
8817 module
->got_var
= real_got
;
8820 * Same for the init_var
8822 if (module
->llvm_only
) {
8823 inited_type
= LLVMArrayType (LLVMInt8Type (), module
->max_inited_idx
+ 1);
8824 real_inited
= LLVMAddGlobal (module
->lmodule
, inited_type
, "mono_inited");
8825 LLVMSetInitializer (real_inited
, LLVMConstNull (inited_type
));
8826 LLVMSetLinkage (real_inited
, LLVMInternalLinkage
);
8827 mono_llvm_replace_uses_of (module
->inited_var
, real_inited
);
8828 LLVMDeleteGlobal (module
->inited_var
);
8831 if (module
->llvm_only
) {
8832 emit_get_method (&aot_module
);
8833 emit_get_unbox_tramp (&aot_module
);
8836 emit_llvm_used (&aot_module
);
8837 emit_dbg_info (&aot_module
, filename
, cu_name
);
8838 emit_aot_file_info (&aot_module
);
8841 * Replace GOT entries for directly callable methods with the methods themselves.
8842 * It would be easier to implement this by predefining all methods before compiling
8843 * their bodies, but that couldn't handle the case when a method fails to compile
8846 if (module
->llvm_only
) {
8847 GHashTableIter iter
;
8849 GSList
*callers
, *l
;
8851 g_hash_table_iter_init (&iter
, module
->method_to_callers
);
8852 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
8853 LLVMValueRef lmethod
;
8855 if (method
->iflags
& METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED
)
8858 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, method
);
8860 for (l
= callers
; l
; l
= l
->next
) {
8861 LLVMValueRef caller
= (LLVMValueRef
)l
->data
;
8863 mono_llvm_replace_uses_of (caller
, lmethod
);
8869 /* Replace PLT entries for directly callable methods with the methods themselves */
8871 GHashTableIter iter
;
8873 LLVMValueRef callee
;
8875 g_hash_table_iter_init (&iter
, module
->plt_entries_ji
);
8876 while (g_hash_table_iter_next (&iter
, (void**)&ji
, (void**)&callee
)) {
8877 if (mono_aot_is_direct_callable (ji
)) {
8878 LLVMValueRef lmethod
;
8880 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, ji
->data
.method
);
8881 /* The types might not match because the caller might pass an rgctx */
8882 if (lmethod
&& LLVMTypeOf (callee
) == LLVMTypeOf (lmethod
)) {
8883 mono_llvm_replace_uses_of (callee
, lmethod
);
8884 mono_aot_mark_unused_llvm_plt_entry (ji
);
8894 if (LLVMVerifyModule (module
->lmodule
, LLVMReturnStatusAction
, &verifier_err
)) {
8895 printf ("%s\n", verifier_err
);
8896 g_assert_not_reached ();
8901 LLVMWriteBitcodeToFile (module
->lmodule
, filename
);
8906 md_string (const char *s
)
8908 return LLVMMDString (s
, strlen (s
));
8911 /* Debugging support */
8914 emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
)
8916 LLVMModuleRef lmodule
= module
->lmodule
;
8917 LLVMValueRef args
[16], ver
;
8920 * This can only be enabled when LLVM code is emitted into a separate object
8921 * file, since the AOT compiler also emits dwarf info,
8922 * and the abbrev indexes will not be correct since llvm has added its own
8925 if (!module
->emit_dwarf
)
8928 #if LLVM_API_VERSION > 100
8929 mono_llvm_di_builder_finalize (module
->di_builder
);
8931 LLVMValueRef cu_args
[16], cu
;
8933 char *build_info
, *s
, *dir
;
8936 * Emit dwarf info in the form of LLVM metadata. There is some
8937 * out-of-date documentation at:
8938 * http://llvm.org/docs/SourceLevelDebugging.html
8939 * but most of this was gathered from the llvm and
8944 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit
, FALSE
);
8945 /* CU name/compilation dir */
8946 dir
= g_path_get_dirname (filename
);
8947 args
[0] = LLVMMDString (cu_name
, strlen (cu_name
));
8948 args
[1] = LLVMMDString (dir
, strlen (dir
));
8949 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 2);
8952 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99
, FALSE
);
8954 build_info
= mono_get_runtime_build_info ();
8955 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8956 cu_args
[n_cuargs
++] = LLVMMDString (s
, strlen (s
));
8957 g_free (build_info
);
8959 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8961 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8962 /* Runtime version */
8963 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8965 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8966 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8968 if (module
->subprogram_mds
) {
8972 mds
= g_new0 (LLVMValueRef
, module
->subprogram_mds
->len
);
8973 for (i
= 0; i
< module
->subprogram_mds
->len
; ++i
)
8974 mds
[i
] = (LLVMValueRef
)g_ptr_array_index (module
->subprogram_mds
, i
);
8975 cu_args
[n_cuargs
++] = LLVMMDNode (mds
, module
->subprogram_mds
->len
);
8977 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8980 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8981 /* Imported modules */
8982 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8984 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8985 /* DebugEmissionKind = FullDebug */
8986 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8987 cu
= LLVMMDNode (cu_args
, n_cuargs
);
8988 LLVMAddNamedMetadataOperand (lmodule
, "llvm.dbg.cu", cu
);
8991 #if LLVM_API_VERSION > 100
8992 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8993 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8994 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8995 ver
= LLVMMDNode (args
, 3);
8996 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8998 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8999 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9000 args
[2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE
);
9001 ver
= LLVMMDNode (args
, 3);
9002 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9004 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9005 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9006 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
9007 ver
= LLVMMDNode (args
, 3);
9008 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9010 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9011 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9012 args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9013 ver
= LLVMMDNode (args
, 3);
9014 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
9019 emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
)
9021 MonoLLVMModule
*module
= ctx
->module
;
9022 MonoDebugMethodInfo
*minfo
= ctx
->minfo
;
9023 char *source_file
, *dir
, *filename
;
9024 LLVMValueRef md
, args
[16], ctx_args
[16], md_args
[64], type_args
[16], ctx_md
, type_md
;
9025 MonoSymSeqPoint
*sym_seq_points
;
9031 mono_debug_symfile_get_seq_points (minfo
, &source_file
, NULL
, NULL
, &sym_seq_points
, &n_seq_points
);
9033 source_file
= g_strdup ("<unknown>");
9034 dir
= g_path_get_dirname (source_file
);
9035 filename
= g_path_get_basename (source_file
);
9037 #if LLVM_API_VERSION > 100
9038 return mono_llvm_di_create_function (module
->di_builder
, module
->cu
, method
, cfg
->method
->name
, name
, dir
, filename
, n_seq_points
? sym_seq_points
[0].line
: 1);
9041 ctx_args
[0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE
);
9042 args
[0] = md_string (filename
);
9043 args
[1] = md_string (dir
);
9044 ctx_args
[1] = LLVMMDNode (args
, 2);
9045 ctx_md
= LLVMMDNode (ctx_args
, 2);
9047 type_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type
, FALSE
);
9048 type_args
[1] = NULL
;
9049 type_args
[2] = NULL
;
9050 type_args
[3] = LLVMMDString ("", 0);
9051 type_args
[4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9052 type_args
[5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9053 type_args
[6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9054 type_args
[7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
9055 type_args
[8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9056 type_args
[9] = NULL
;
9057 type_args
[10] = NULL
;
9058 type_args
[11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9059 type_args
[12] = NULL
;
9060 type_args
[13] = NULL
;
9061 type_args
[14] = NULL
;
9062 type_md
= LLVMMDNode (type_args
, 14);
9064 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9065 md_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram
, FALSE
);
9066 /* Source directory + file pair */
9067 args
[0] = md_string (filename
);
9068 args
[1] = md_string (dir
);
9069 md_args
[1] = LLVMMDNode (args
,2);
9070 md_args
[2] = ctx_md
;
9071 md_args
[3] = md_string (cfg
->method
->name
);
9072 md_args
[4] = md_string (name
);
9073 md_args
[5] = md_string (name
);
9076 md_args
[6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points
[0].line
, FALSE
);
9078 md_args
[6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9080 md_args
[7] = type_md
;
9082 md_args
[8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9084 md_args
[9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9086 md_args
[10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
9087 /* Index into a virtual function */
9088 md_args
[11] = NULL
;
9089 md_args
[12] = NULL
;
9091 md_args
[13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
9093 md_args
[14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
9094 /* Pointer to LLVM function */
9095 md_args
[15] = method
;
9096 /* Function template parameter */
9097 md_args
[16] = NULL
;
9098 /* Function declaration descriptor */
9099 md_args
[17] = NULL
;
9100 /* List of function variables */
9101 md_args
[18] = LLVMMDNode (args
, 0);
9103 md_args
[19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
9104 md
= LLVMMDNode (md_args
, 20);
9106 if (!module
->subprogram_mds
)
9107 module
->subprogram_mds
= g_ptr_array_new ();
9108 g_ptr_array_add (module
->subprogram_mds
, md
);
9112 g_free (source_file
);
9113 g_free (sym_seq_points
);
9119 emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
)
9121 MonoCompile
*cfg
= ctx
->cfg
;
9123 if (ctx
->minfo
&& cil_code
&& cil_code
>= cfg
->header
->code
&& cil_code
< cfg
->header
->code
+ cfg
->header
->code_size
) {
9124 MonoDebugSourceLocation
*loc
;
9125 LLVMValueRef loc_md
;
9127 loc
= mono_debug_symfile_lookup_location (ctx
->minfo
, cil_code
- cfg
->header
->code
);
9130 #if LLVM_API_VERSION > 100
9131 loc_md
= mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, loc
->row
, loc
->column
);
9132 mono_llvm_di_set_location (builder
, loc_md
);
9134 LLVMValueRef md_args
[16];
9138 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->row
, FALSE
);
9139 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->column
, FALSE
);
9140 md_args
[nmd_args
++] = ctx
->dbg_md
;
9141 md_args
[nmd_args
++] = NULL
;
9142 loc_md
= LLVMMDNode (md_args
, nmd_args
);
9143 LLVMSetCurrentDebugLocation (builder
, loc_md
);
9145 mono_debug_symfile_free_location (loc
);
9151 default_mono_llvm_unhandled_exception (void)
9153 MonoJitTlsData
*jit_tls
= mono_get_jit_tls ();
9154 MonoObject
*target
= mono_gchandle_get_target (jit_tls
->thrown_exc
);
9156 mono_unhandled_exception (target
);
9157 mono_invoke_unhandled_exception_hook (target
);
9158 g_assert_not_reached ();
9163 - Emit LLVM IR from the mono IR using the LLVM C API.
9164 - The original arch specific code remains, so we can fall back to it if we run
9165 into something we can't handle.
9169 A partial list of issues:
9170 - Handling of opcodes which can throw exceptions.
9172 In the mono JIT, these are implemented using code like this:
9179 push throw_pos - method
9180 call <exception trampoline>
9182 The problematic part is push throw_pos - method, which cannot be represented
9183 in the LLVM IR, since it does not support label values.
9184 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9185 be implemented in JIT mode ?
9186 -> a possible but slower implementation would use the normal exception
9187 throwing code but it would need to control the placement of the throw code
9188 (it needs to be exactly after the compare+branch).
9189 -> perhaps add a PC offset intrinsics ?
9191 - efficient implementation of .ovf opcodes.
9193 These are currently implemented as:
9194 <ins which sets the condition codes>
9197 Some overflow opcodes are now supported by LLVM SVN.
9199 - exception handling, unwinding.
9200 - SSA is disabled for methods with exception handlers
9201 - How to obtain unwind info for LLVM compiled methods ?
9202 -> this is now solved by converting the unwind info generated by LLVM
9204 - LLVM uses the c++ exception handling framework, while we use our home grown
9205 code, and couldn't use the c++ one:
9206 - its not supported under VC++, other exotic platforms.
9207 - it might be impossible to support filter clauses with it.
9211 The trampolines need a predictable call sequence, since they need to disasm
9212 the calling code to obtain register numbers / offsets.
9214 LLVM currently generates this code in non-JIT mode:
9215 mov -0x98(%rax),%eax
9217 Here, the vtable pointer is lost.
9218 -> solution: use one vtable trampoline per class.
9220 - passing/receiving the IMT pointer/RGCTX.
9221 -> solution: pass them as normal arguments ?
9225 LLVM does not allow the specification of argument registers etc. This means
9226 that all calls are made according to the platform ABI.
9228 - passing/receiving vtypes.
9230 Vtypes passed/received in registers are handled by the front end by using
9231 a signature with scalar arguments, and loading the parts of the vtype into those
9234 Vtypes passed on the stack are handled using the 'byval' attribute.
9238 Supported though alloca, we need to emit the load/store code.
9242 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9243 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9244 This is made easier because the IR is already in SSA form.
9245 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9246 types are frequently used incorrectly.
9251 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9252 it with the file containing the methods emitted by the JIT and the AOT data
9256 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9257 * - each bblock should end with a branch
9258 * - setting the return value, making cfg->ret non-volatile
9259 * - avoid some transformations in the JIT which make it harder for us to generate
9261 * - use pointer types to help optimizations.
9264 #else /* DISABLE_JIT */
9267 mono_llvm_cleanup (void)
9272 mono_llvm_free_domain_info (MonoDomain
*domain
)
9277 mono_llvm_init (void)
9282 default_mono_llvm_unhandled_exception (void)
9286 #endif /* DISABLE_JIT */