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.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to
, size_t count
) { memset (to
, 0, count
); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule
;
55 LLVMValueRef throw_icall
, rethrow
, match_exc
, throw_corlib_exception
, resume_eh
;
56 GHashTable
*llvm_types
;
58 const char *got_symbol
;
59 const char *get_method_symbol
;
60 const char *get_unbox_tramp_symbol
;
61 GHashTable
*plt_entries
;
62 GHashTable
*plt_entries_ji
;
63 GHashTable
*method_to_lmethod
;
64 GHashTable
*direct_callables
;
69 GPtrArray
*subprogram_mds
;
71 LLVMExecutionEngineRef ee
;
72 gboolean external_symbols
;
75 LLVMValueRef personality
;
78 MonoAssembly
*assembly
;
80 MonoAotFileInfo aot_info
;
81 const char *jit_got_symbol
;
82 const char *eh_frame_symbol
;
83 LLVMValueRef get_method
, get_unbox_tramp
;
84 LLVMValueRef init_method
, init_method_gshared_mrgctx
, init_method_gshared_this
, init_method_gshared_vtable
;
85 LLVMValueRef code_start
, code_end
;
86 LLVMValueRef inited_var
;
87 int max_inited_idx
, max_method_idx
;
88 gboolean has_jitted_code
;
91 GHashTable
*idx_to_lmethod
;
92 GHashTable
*idx_to_unbox_tramp
;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable
*method_to_callers
;
95 LLVMContextRef context
;
96 LLVMValueRef sentinel_exception
;
97 void *di_builder
, *cu
;
98 GHashTable
*objc_selector_to_var
;
102 * Information associated by the backend with mono basic blocks.
105 LLVMBasicBlockRef bblock
, end_bblock
;
106 LLVMValueRef finally_ind
;
107 gboolean added
, invoke_target
;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList
*call_handler_return_bbs
;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb
;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList
*endfinally_switch_ins_list
;
124 * Structure containing emit state
127 MonoMemPool
*mempool
;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable
*emitted_method_decls
;
133 LLVMValueRef lmethod
;
134 MonoLLVMModule
*module
;
135 LLVMModuleRef lmodule
;
137 int sindex
, default_index
, ex_index
;
138 LLVMBuilderRef builder
;
139 LLVMValueRef
*values
, *addresses
;
140 MonoType
**vreg_cli_types
;
142 MonoMethodSignature
*sig
;
144 GHashTable
*region_to_handler
;
145 GHashTable
*clause_to_handler
;
146 LLVMBuilderRef alloca_builder
;
147 LLVMValueRef last_alloca
;
148 LLVMValueRef rgctx_arg
;
149 LLVMValueRef this_arg
;
150 LLVMTypeRef
*vreg_types
;
151 LLVMTypeRef method_type
;
152 LLVMBasicBlockRef init_bb
, inited_bb
;
154 gboolean
*unreachable
;
156 gboolean has_got_access
;
157 gboolean is_linkonce
;
158 int this_arg_pindex
, rgctx_arg_pindex
;
159 LLVMValueRef imt_rgctx_loc
;
160 GHashTable
*llvm_types
;
162 MonoDebugMethodInfo
*minfo
;
164 /* For every clause, the clauses it is nested in */
167 GHashTable
*exc_meta
;
168 GHashTable
*method_to_callers
;
169 GPtrArray
*phi_values
;
170 GPtrArray
*bblock_list
;
172 GHashTable
*jit_callees
;
178 MonoBasicBlock
*in_bb
;
183 * Instruction metadata
184 * This is the same as ins_info, but LREG != IREG.
192 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
193 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
200 /* keep in sync with the enum in mini.h */
203 #include "mini-ops.h"
208 #if SIZEOF_VOID_P == 4
209 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
211 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
214 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
217 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
219 #define TRACE_FAILURE(msg)
223 #define IS_TARGET_X86 1
225 #define IS_TARGET_X86 0
229 #define IS_TARGET_AMD64 1
231 #define IS_TARGET_AMD64 0
234 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
236 static LLVMIntPredicate cond_to_llvm_cond
[] = {
249 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
262 static MonoNativeTlsKey current_cfg_tls_id
;
264 static MonoLLVMModule aot_module
;
266 static GHashTable
*intrins_id_to_name
;
267 static GHashTable
*intrins_name_to_id
;
269 static void init_jit_module (MonoDomain
*domain
);
271 static void emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
);
272 static LLVMValueRef
emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
);
273 static void emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
);
274 static void emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
);
275 static LLVMValueRef
get_intrinsic (EmitContext
*ctx
, const char *name
);
276 static void decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
);
279 set_failure (EmitContext
*ctx
, const char *message
)
281 TRACE_FAILURE (reason
);
282 ctx
->cfg
->exception_message
= g_strdup (message
);
283 ctx
->cfg
->disable_llvm
= TRUE
;
289 * The LLVM type with width == sizeof (gpointer)
294 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
300 return sizeof (gpointer
) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
306 return sizeof (gpointer
) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
312 * Return the size of the LLVM representation of the vtype T.
315 get_vtype_size (MonoType
*t
)
319 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
321 /* LLVMArgAsIArgs depends on this since it stores whole words */
322 while (size
< 2 * sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
329 * simd_class_to_llvm_type:
331 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
334 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
336 if (!strcmp (klass
->name
, "Vector2d")) {
337 return LLVMVectorType (LLVMDoubleType (), 2);
338 } else if (!strcmp (klass
->name
, "Vector2l")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass
->name
, "Vector2ul")) {
341 return LLVMVectorType (LLVMInt64Type (), 2);
342 } else if (!strcmp (klass
->name
, "Vector4i")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass
->name
, "Vector4ui")) {
345 return LLVMVectorType (LLVMInt32Type (), 4);
346 } else if (!strcmp (klass
->name
, "Vector4f")) {
347 return LLVMVectorType (LLVMFloatType (), 4);
348 } else if (!strcmp (klass
->name
, "Vector8s")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass
->name
, "Vector8us")) {
351 return LLVMVectorType (LLVMInt16Type (), 8);
352 } else if (!strcmp (klass
->name
, "Vector16sb")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
354 } else if (!strcmp (klass
->name
, "Vector16b")) {
355 return LLVMVectorType (LLVMInt8Type (), 16);
357 printf ("%s\n", klass
->name
);
363 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
364 static inline G_GNUC_UNUSED LLVMTypeRef
365 type_to_simd_type (int type
)
369 return LLVMVectorType (LLVMInt8Type (), 16);
371 return LLVMVectorType (LLVMInt16Type (), 8);
373 return LLVMVectorType (LLVMInt32Type (), 4);
375 return LLVMVectorType (LLVMInt64Type (), 2);
377 return LLVMVectorType (LLVMDoubleType (), 2);
379 return LLVMVectorType (LLVMFloatType (), 4);
381 g_assert_not_reached ();
387 create_llvm_type_for_type (MonoLLVMModule
*module
, MonoClass
*klass
)
389 int i
, size
, nfields
, esize
;
390 LLVMTypeRef
*eltypes
;
395 t
= &klass
->byval_arg
;
397 if (mini_type_is_hfa (t
, &nfields
, &esize
)) {
399 * This is needed on arm64 where HFAs are returned in
403 eltypes
= g_new (LLVMTypeRef
, size
);
404 for (i
= 0; i
< size
; ++i
)
405 eltypes
[i
] = esize
== 4 ? LLVMFloatType () : LLVMDoubleType ();
407 size
= get_vtype_size (t
);
409 eltypes
= g_new (LLVMTypeRef
, size
);
410 for (i
= 0; i
< size
; ++i
)
411 eltypes
[i
] = LLVMInt8Type ();
414 name
= mono_type_full_name (&klass
->byval_arg
);
415 ltype
= LLVMStructCreateNamed (module
->context
, name
);
416 LLVMStructSetBody (ltype
, eltypes
, size
, FALSE
);
426 * Return the LLVM type corresponding to T.
429 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
431 t
= mini_get_underlying_type (t
);
435 return LLVMVoidType ();
437 return LLVMInt8Type ();
439 return LLVMInt16Type ();
441 return LLVMInt32Type ();
443 return LLVMInt8Type ();
445 return LLVMInt16Type ();
447 return LLVMInt32Type ();
448 case MONO_TYPE_BOOLEAN
:
449 return LLVMInt8Type ();
452 return LLVMInt64Type ();
454 return LLVMInt16Type ();
456 return LLVMFloatType ();
458 return LLVMDoubleType ();
461 return IntPtrType ();
462 case MONO_TYPE_OBJECT
:
463 case MONO_TYPE_CLASS
:
464 case MONO_TYPE_ARRAY
:
465 case MONO_TYPE_SZARRAY
:
466 case MONO_TYPE_STRING
:
468 return ObjRefType ();
471 /* Because of generic sharing */
472 return ObjRefType ();
473 case MONO_TYPE_GENERICINST
:
474 if (!mono_type_generic_inst_is_valuetype (t
))
475 return ObjRefType ();
477 case MONO_TYPE_VALUETYPE
:
478 case MONO_TYPE_TYPEDBYREF
: {
482 klass
= mono_class_from_mono_type (t
);
484 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
485 return simd_class_to_llvm_type (ctx
, klass
);
488 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
490 ltype
= (LLVMTypeRef
)g_hash_table_lookup (ctx
->module
->llvm_types
, klass
);
492 ltype
= create_llvm_type_for_type (ctx
->module
, klass
);
493 g_hash_table_insert (ctx
->module
->llvm_types
, klass
, ltype
);
499 printf ("X: %d\n", t
->type
);
500 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
501 ctx
->cfg
->disable_llvm
= TRUE
;
509 * Return whenever T is an unsigned int type.
512 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
514 t
= mini_get_underlying_type (t
);
530 * type_to_llvm_arg_type:
532 * Same as type_to_llvm_type, but treat i8/i16 as i32.
535 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
537 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
539 if (ctx
->cfg
->llvm_only
)
543 * This works on all abis except arm64/ios which passes multiple
544 * arguments in one stack slot.
547 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
549 * LLVM generates code which only sets the lower bits, while JITted
550 * code expects all the bits to be set.
552 ptype
= LLVMInt32Type ();
560 * llvm_type_to_stack_type:
562 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
565 static G_GNUC_UNUSED LLVMTypeRef
566 llvm_type_to_stack_type (MonoCompile
*cfg
, LLVMTypeRef type
)
570 if (type
== LLVMInt8Type ())
571 return LLVMInt32Type ();
572 else if (type
== LLVMInt16Type ())
573 return LLVMInt32Type ();
574 else if (!cfg
->r4fp
&& type
== LLVMFloatType ())
575 return LLVMDoubleType ();
581 * regtype_to_llvm_type:
583 * Return the LLVM type corresponding to the regtype C used in instruction
587 regtype_to_llvm_type (char c
)
591 return LLVMInt32Type ();
593 return LLVMInt64Type ();
595 return LLVMDoubleType ();
604 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
607 op_to_llvm_type (int opcode
)
612 return LLVMInt8Type ();
615 return LLVMInt8Type ();
618 return LLVMInt16Type ();
621 return LLVMInt16Type ();
624 return LLVMInt32Type ();
627 return LLVMInt32Type ();
629 return LLVMInt64Type ();
631 return LLVMFloatType ();
633 return LLVMDoubleType ();
635 return LLVMInt64Type ();
637 return LLVMInt32Type ();
639 return LLVMInt64Type ();
644 return LLVMInt8Type ();
649 return LLVMInt16Type ();
651 return LLVMInt32Type ();
654 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
661 return LLVMInt32Type ();
668 return LLVMInt64Type ();
670 printf ("%s\n", mono_inst_name (opcode
));
671 g_assert_not_reached ();
676 #define CLAUSE_START(clause) ((clause)->try_offset)
677 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
680 * load_store_to_llvm_type:
682 * Return the size/sign/zero extension corresponding to the load/store opcode
686 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
692 case OP_LOADI1_MEMBASE
:
693 case OP_STOREI1_MEMBASE_REG
:
694 case OP_STOREI1_MEMBASE_IMM
:
695 case OP_ATOMIC_LOAD_I1
:
696 case OP_ATOMIC_STORE_I1
:
699 return LLVMInt8Type ();
700 case OP_LOADU1_MEMBASE
:
702 case OP_ATOMIC_LOAD_U1
:
703 case OP_ATOMIC_STORE_U1
:
706 return LLVMInt8Type ();
707 case OP_LOADI2_MEMBASE
:
708 case OP_STOREI2_MEMBASE_REG
:
709 case OP_STOREI2_MEMBASE_IMM
:
710 case OP_ATOMIC_LOAD_I2
:
711 case OP_ATOMIC_STORE_I2
:
714 return LLVMInt16Type ();
715 case OP_LOADU2_MEMBASE
:
717 case OP_ATOMIC_LOAD_U2
:
718 case OP_ATOMIC_STORE_U2
:
721 return LLVMInt16Type ();
722 case OP_LOADI4_MEMBASE
:
723 case OP_LOADU4_MEMBASE
:
726 case OP_STOREI4_MEMBASE_REG
:
727 case OP_STOREI4_MEMBASE_IMM
:
728 case OP_ATOMIC_LOAD_I4
:
729 case OP_ATOMIC_STORE_I4
:
730 case OP_ATOMIC_LOAD_U4
:
731 case OP_ATOMIC_STORE_U4
:
733 return LLVMInt32Type ();
734 case OP_LOADI8_MEMBASE
:
736 case OP_STOREI8_MEMBASE_REG
:
737 case OP_STOREI8_MEMBASE_IMM
:
738 case OP_ATOMIC_LOAD_I8
:
739 case OP_ATOMIC_STORE_I8
:
740 case OP_ATOMIC_LOAD_U8
:
741 case OP_ATOMIC_STORE_U8
:
743 return LLVMInt64Type ();
744 case OP_LOADR4_MEMBASE
:
745 case OP_STORER4_MEMBASE_REG
:
746 case OP_ATOMIC_LOAD_R4
:
747 case OP_ATOMIC_STORE_R4
:
749 return LLVMFloatType ();
750 case OP_LOADR8_MEMBASE
:
751 case OP_STORER8_MEMBASE_REG
:
752 case OP_ATOMIC_LOAD_R8
:
753 case OP_ATOMIC_STORE_R8
:
755 return LLVMDoubleType ();
756 case OP_LOAD_MEMBASE
:
758 case OP_STORE_MEMBASE_REG
:
759 case OP_STORE_MEMBASE_IMM
:
760 *size
= sizeof (gpointer
);
761 return IntPtrType ();
763 g_assert_not_reached ();
771 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
774 ovf_op_to_intrins (int opcode
)
778 return "llvm.sadd.with.overflow.i32";
780 return "llvm.uadd.with.overflow.i32";
782 return "llvm.ssub.with.overflow.i32";
784 return "llvm.usub.with.overflow.i32";
786 return "llvm.smul.with.overflow.i32";
788 return "llvm.umul.with.overflow.i32";
790 return "llvm.sadd.with.overflow.i64";
792 return "llvm.uadd.with.overflow.i64";
794 return "llvm.ssub.with.overflow.i64";
796 return "llvm.usub.with.overflow.i64";
798 return "llvm.smul.with.overflow.i64";
800 return "llvm.umul.with.overflow.i64";
802 g_assert_not_reached ();
808 simd_op_to_intrins (int opcode
)
811 #if defined(TARGET_X86) || defined(TARGET_AMD64)
813 return "llvm.x86.sse2.min.pd";
815 return "llvm.x86.sse.min.ps";
817 return "llvm.x86.sse2.max.pd";
819 return "llvm.x86.sse.max.ps";
821 return "llvm.x86.sse3.hadd.pd";
823 return "llvm.x86.sse3.hadd.ps";
825 return "llvm.x86.sse3.hsub.pd";
827 return "llvm.x86.sse3.hsub.ps";
829 return "llvm.x86.sse3.addsub.ps";
831 return "llvm.x86.sse3.addsub.pd";
832 case OP_EXTRACT_MASK
:
833 return "llvm.x86.sse2.pmovmskb.128";
836 return "llvm.x86.sse2.psrli.w";
839 return "llvm.x86.sse2.psrli.d";
842 return "llvm.x86.sse2.psrli.q";
845 return "llvm.x86.sse2.pslli.w";
848 return "llvm.x86.sse2.pslli.d";
851 return "llvm.x86.sse2.pslli.q";
854 return "llvm.x86.sse2.psrai.w";
857 return "llvm.x86.sse2.psrai.d";
859 return "llvm.x86.sse2.padds.b";
861 return "llvm.x86.sse2.padds.w";
863 return "llvm.x86.sse2.psubs.b";
865 return "llvm.x86.sse2.psubs.w";
866 case OP_PADDB_SAT_UN
:
867 return "llvm.x86.sse2.paddus.b";
868 case OP_PADDW_SAT_UN
:
869 return "llvm.x86.sse2.paddus.w";
870 case OP_PSUBB_SAT_UN
:
871 return "llvm.x86.sse2.psubus.b";
872 case OP_PSUBW_SAT_UN
:
873 return "llvm.x86.sse2.psubus.w";
875 return "llvm.x86.sse2.pavg.b";
877 return "llvm.x86.sse2.pavg.w";
879 return "llvm.x86.sse.sqrt.ps";
881 return "llvm.x86.sse2.sqrt.pd";
883 return "llvm.x86.sse.rsqrt.ps";
885 return "llvm.x86.sse.rcp.ps";
887 return "llvm.x86.sse2.cvtdq2pd";
889 return "llvm.x86.sse2.cvtdq2ps";
891 return "llvm.x86.sse2.cvtpd2dq";
893 return "llvm.x86.sse2.cvtps2dq";
895 return "llvm.x86.sse2.cvtpd2ps";
897 return "llvm.x86.sse2.cvtps2pd";
899 return "llvm.x86.sse2.cvttpd2dq";
901 return "llvm.x86.sse2.cvttps2dq";
903 return "llvm.x86.sse2.packsswb.128";
905 return "llvm.x86.sse2.packssdw.128";
907 return "llvm.x86.sse2.packuswb.128";
909 return "llvm.x86.sse41.packusdw";
911 return "llvm.x86.sse2.pmulh.w";
912 case OP_PMULW_HIGH_UN
:
913 return "llvm.x86.sse2.pmulhu.w";
916 g_assert_not_reached ();
922 simd_op_to_llvm_type (int opcode
)
924 #if defined(TARGET_X86) || defined(TARGET_AMD64)
928 return type_to_simd_type (MONO_TYPE_R8
);
931 return type_to_simd_type (MONO_TYPE_I8
);
934 return type_to_simd_type (MONO_TYPE_I4
);
939 return type_to_simd_type (MONO_TYPE_I2
);
943 return type_to_simd_type (MONO_TYPE_I1
);
945 return type_to_simd_type (MONO_TYPE_R4
);
948 return type_to_simd_type (MONO_TYPE_I4
);
952 return type_to_simd_type (MONO_TYPE_R8
);
956 return type_to_simd_type (MONO_TYPE_R4
);
957 case OP_EXTRACT_MASK
:
958 return type_to_simd_type (MONO_TYPE_I1
);
964 return type_to_simd_type (MONO_TYPE_R4
);
967 return type_to_simd_type (MONO_TYPE_R8
);
969 g_assert_not_reached ();
980 * Return the LLVM basic block corresponding to BB.
982 static LLVMBasicBlockRef
983 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
985 char bb_name_buf
[128];
988 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
989 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
990 int clause_index
= (mono_get_block_region_notry (ctx
->cfg
, bb
->region
) >> 8) - 1;
991 sprintf (bb_name_buf
, "EH_CLAUSE%d_BB%d", clause_index
, bb
->block_num
);
992 bb_name
= bb_name_buf
;
993 } else if (bb
->block_num
< 256) {
994 if (!ctx
->module
->bb_names
) {
995 ctx
->module
->bb_names_len
= 256;
996 ctx
->module
->bb_names
= g_new0 (char*, ctx
->module
->bb_names_len
);
998 if (!ctx
->module
->bb_names
[bb
->block_num
]) {
1001 n
= g_strdup_printf ("BB%d", bb
->block_num
);
1002 mono_memory_barrier ();
1003 ctx
->module
->bb_names
[bb
->block_num
] = n
;
1005 bb_name
= ctx
->module
->bb_names
[bb
->block_num
];
1007 sprintf (bb_name_buf
, "BB%d", bb
->block_num
);
1008 bb_name
= bb_name_buf
;
1011 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1012 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
1015 return ctx
->bblocks
[bb
->block_num
].bblock
;
1021 * Return the last LLVM bblock corresponding to BB.
1022 * This might not be equal to the bb returned by get_bb () since we need to generate
1023 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1025 static LLVMBasicBlockRef
1026 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
1029 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
1032 static LLVMBasicBlockRef
1033 gen_bb (EmitContext
*ctx
, const char *prefix
)
1037 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
1038 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1044 * Return the target of the patch identified by TYPE and TARGET.
1047 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
1053 memset (&ji
, 0, sizeof (ji
));
1055 ji
.data
.target
= target
;
1057 res
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
, &error
);
1058 mono_error_assert_ok (&error
);
1066 * Emit code to convert the LLVM value V to DTYPE.
1069 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
1071 LLVMTypeRef stype
= LLVMTypeOf (v
);
1073 if (stype
!= dtype
) {
1074 gboolean ext
= FALSE
;
1077 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1079 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
1081 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
1085 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
1087 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
1088 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
1091 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1092 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1093 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1095 if (stype
== LLVMInt16Type () && dtype
== LLVMInt8Type ())
1096 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
1097 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
1098 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
1100 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1101 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1102 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
1103 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
1104 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
1105 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
1107 if (mono_arch_is_soft_float ()) {
1108 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
1109 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1110 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
1111 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
1114 if (LLVMGetTypeKind (stype
) == LLVMVectorTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMVectorTypeKind
)
1115 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
1118 LLVMDumpValue (LLVMConstNull (dtype
));
1119 g_assert_not_reached ();
1127 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
1129 return convert_full (ctx
, v
, dtype
, FALSE
);
1133 * emit_volatile_load:
1135 * If vreg is volatile, emit a load from its address.
1138 emit_volatile_load (EmitContext
*ctx
, int vreg
)
1142 LLVMValueRef v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
1143 t
= ctx
->vreg_cli_types
[vreg
];
1144 if (t
&& !t
->byref
) {
1146 * Might have to zero extend since llvm doesn't have
1149 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
|| t
->type
== MONO_TYPE_CHAR
|| t
->type
== MONO_TYPE_BOOLEAN
)
1150 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1151 else if (t
->type
== MONO_TYPE_I1
|| t
->type
== MONO_TYPE_I2
)
1152 v
= LLVMBuildSExt (ctx
->builder
, v
, LLVMInt32Type (), "");
1153 else if (t
->type
== MONO_TYPE_U8
)
1154 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
1161 * emit_volatile_store:
1163 * If VREG is volatile, emit a store from its value to its address.
1166 emit_volatile_store (EmitContext
*ctx
, int vreg
)
1168 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
1170 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1171 g_assert (ctx
->addresses
[vreg
]);
1172 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
1177 sig_to_llvm_sig_no_cinfo (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1179 LLVMTypeRef ret_type
;
1180 LLVMTypeRef
*param_types
= NULL
;
1185 rtype
= mini_get_underlying_type (sig
->ret
);
1186 ret_type
= type_to_llvm_type (ctx
, rtype
);
1190 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1194 param_types
[pindex
++] = ThisType ();
1195 for (i
= 0; i
< sig
->param_count
; ++i
)
1196 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
1198 if (!ctx_ok (ctx
)) {
1199 g_free (param_types
);
1203 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1204 g_free (param_types
);
1210 * sig_to_llvm_sig_full:
1212 * Return the LLVM signature corresponding to the mono signature SIG using the
1213 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1216 sig_to_llvm_sig_full (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
)
1218 LLVMTypeRef ret_type
;
1219 LLVMTypeRef
*param_types
= NULL
;
1221 int i
, j
, pindex
, vret_arg_pindex
= 0;
1222 gboolean vretaddr
= FALSE
;
1226 return sig_to_llvm_sig_no_cinfo (ctx
, sig
);
1228 rtype
= mini_get_underlying_type (sig
->ret
);
1229 ret_type
= type_to_llvm_type (ctx
, rtype
);
1233 switch (cinfo
->ret
.storage
) {
1234 case LLVMArgVtypeInReg
:
1235 /* LLVM models this by returning an aggregate value */
1236 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1237 LLVMTypeRef members
[2];
1239 members
[0] = IntPtrType ();
1240 ret_type
= LLVMStructType (members
, 1, FALSE
);
1241 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgNone
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
1243 ret_type
= LLVMVoidType ();
1244 } else if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgInIReg
) {
1245 LLVMTypeRef members
[2];
1247 members
[0] = IntPtrType ();
1248 members
[1] = IntPtrType ();
1249 ret_type
= LLVMStructType (members
, 2, FALSE
);
1251 g_assert_not_reached ();
1254 case LLVMArgVtypeByVal
:
1255 /* Vtype returned normally by val */
1257 case LLVMArgVtypeAsScalar
: {
1258 int size
= mono_class_value_size (mono_class_from_mono_type (rtype
), NULL
);
1259 /* LLVM models this by returning an int */
1260 if (size
< SIZEOF_VOID_P
) {
1261 g_assert (cinfo
->ret
.nslots
== 1);
1262 ret_type
= LLVMIntType (size
* 8);
1264 g_assert (cinfo
->ret
.nslots
== 1 || cinfo
->ret
.nslots
== 2);
1265 ret_type
= LLVMIntType (cinfo
->ret
.nslots
* sizeof (mgreg_t
) * 8);
1269 case LLVMArgAsIArgs
:
1270 ret_type
= LLVMArrayType (IntPtrType (), cinfo
->ret
.nslots
);
1272 case LLVMArgFpStruct
: {
1273 /* Vtype returned as a fp struct */
1274 LLVMTypeRef members
[16];
1276 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1277 for (i
= 0; i
< cinfo
->ret
.nslots
; ++i
)
1278 members
[i
] = cinfo
->ret
.esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1279 ret_type
= LLVMStructType (members
, cinfo
->ret
.nslots
, FALSE
);
1282 case LLVMArgVtypeByRef
:
1283 /* Vtype returned using a hidden argument */
1284 ret_type
= LLVMVoidType ();
1286 case LLVMArgVtypeRetAddr
:
1287 case LLVMArgGsharedvtFixed
:
1288 case LLVMArgGsharedvtFixedVtype
:
1289 case LLVMArgGsharedvtVariable
:
1291 ret_type
= LLVMVoidType ();
1297 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 8) + 3);
1299 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
) {
1301 * Has to be the first argument because of the sret argument attribute
1302 * FIXME: This might conflict with passing 'this' as the first argument, but
1303 * this is only used on arm64 which has a dedicated struct return register.
1305 cinfo
->vret_arg_pindex
= pindex
;
1306 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->ret
);
1307 if (!ctx_ok (ctx
)) {
1308 g_free (param_types
);
1311 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1314 if (!ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1315 cinfo
->rgctx_arg_pindex
= pindex
;
1316 param_types
[pindex
] = ctx
->module
->ptr_type
;
1319 if (cinfo
->imt_arg
) {
1320 cinfo
->imt_arg_pindex
= pindex
;
1321 param_types
[pindex
] = ctx
->module
->ptr_type
;
1325 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1326 vret_arg_pindex
= pindex
;
1327 if (cinfo
->vret_arg_index
== 1) {
1328 /* Add the slots consumed by the first argument */
1329 LLVMArgInfo
*ainfo
= &cinfo
->args
[0];
1330 switch (ainfo
->storage
) {
1331 case LLVMArgVtypeInReg
:
1332 for (j
= 0; j
< 2; ++j
) {
1333 if (ainfo
->pair_storage
[j
] == LLVMArgInIReg
)
1342 cinfo
->vret_arg_pindex
= vret_arg_pindex
;
1345 if (vretaddr
&& vret_arg_pindex
== pindex
)
1346 param_types
[pindex
++] = IntPtrType ();
1348 cinfo
->this_arg_pindex
= pindex
;
1349 param_types
[pindex
++] = ThisType ();
1350 cinfo
->args
[0].pindex
= cinfo
->this_arg_pindex
;
1352 if (vretaddr
&& vret_arg_pindex
== pindex
)
1353 param_types
[pindex
++] = IntPtrType ();
1354 for (i
= 0; i
< sig
->param_count
; ++i
) {
1355 LLVMArgInfo
*ainfo
= &cinfo
->args
[i
+ sig
->hasthis
];
1357 if (vretaddr
&& vret_arg_pindex
== pindex
)
1358 param_types
[pindex
++] = IntPtrType ();
1359 ainfo
->pindex
= pindex
;
1361 switch (ainfo
->storage
) {
1362 case LLVMArgVtypeInReg
:
1363 for (j
= 0; j
< 2; ++j
) {
1364 switch (ainfo
->pair_storage
[j
]) {
1366 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
1371 g_assert_not_reached ();
1375 case LLVMArgVtypeByVal
:
1376 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1379 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1382 case LLVMArgAsIArgs
:
1383 param_types
[pindex
] = LLVMArrayType (IntPtrType (), ainfo
->nslots
);
1386 case LLVMArgVtypeByRef
:
1387 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1390 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
1393 case LLVMArgAsFpArgs
: {
1396 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1397 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
1398 param_types
[pindex
++] = LLVMDoubleType ();
1399 for (j
= 0; j
< ainfo
->nslots
; ++j
)
1400 param_types
[pindex
++] = ainfo
->esize
== 8 ? LLVMDoubleType () : LLVMFloatType ();
1403 case LLVMArgVtypeAsScalar
:
1404 g_assert_not_reached ();
1406 case LLVMArgGsharedvtFixed
:
1407 case LLVMArgGsharedvtFixedVtype
:
1408 param_types
[pindex
++] = LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0);
1410 case LLVMArgGsharedvtVariable
:
1411 param_types
[pindex
++] = LLVMPointerType (IntPtrType (), 0);
1414 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, ainfo
->type
);
1418 if (!ctx_ok (ctx
)) {
1419 g_free (param_types
);
1422 if (vretaddr
&& vret_arg_pindex
== pindex
)
1423 param_types
[pindex
++] = IntPtrType ();
1424 if (ctx
->llvm_only
&& cinfo
->rgctx_arg
) {
1425 /* Pass the rgctx as the last argument */
1426 cinfo
->rgctx_arg_pindex
= pindex
;
1427 param_types
[pindex
] = ctx
->module
->ptr_type
;
1431 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
1432 g_free (param_types
);
1438 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
)
1440 return sig_to_llvm_sig_full (ctx
, sig
, NULL
);
1444 * LLVMFunctionType1:
1446 * Create an LLVM function type from the arguments.
1448 static G_GNUC_UNUSED LLVMTypeRef
1449 LLVMFunctionType0 (LLVMTypeRef ReturnType
,
1452 return LLVMFunctionType (ReturnType
, NULL
, 0, IsVarArg
);
1456 * LLVMFunctionType1:
1458 * Create an LLVM function type from the arguments.
1460 static G_GNUC_UNUSED LLVMTypeRef
1461 LLVMFunctionType1 (LLVMTypeRef ReturnType
,
1462 LLVMTypeRef ParamType1
,
1465 LLVMTypeRef param_types
[1];
1467 param_types
[0] = ParamType1
;
1469 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
1473 * LLVMFunctionType2:
1475 * Create an LLVM function type from the arguments.
1477 static G_GNUC_UNUSED LLVMTypeRef
1478 LLVMFunctionType2 (LLVMTypeRef ReturnType
,
1479 LLVMTypeRef ParamType1
,
1480 LLVMTypeRef ParamType2
,
1483 LLVMTypeRef param_types
[2];
1485 param_types
[0] = ParamType1
;
1486 param_types
[1] = ParamType2
;
1488 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
1492 * LLVMFunctionType3:
1494 * Create an LLVM function type from the arguments.
1496 static G_GNUC_UNUSED LLVMTypeRef
1497 LLVMFunctionType3 (LLVMTypeRef ReturnType
,
1498 LLVMTypeRef ParamType1
,
1499 LLVMTypeRef ParamType2
,
1500 LLVMTypeRef ParamType3
,
1503 LLVMTypeRef param_types
[3];
1505 param_types
[0] = ParamType1
;
1506 param_types
[1] = ParamType2
;
1507 param_types
[2] = ParamType3
;
1509 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
1512 static G_GNUC_UNUSED LLVMTypeRef
1513 LLVMFunctionType5 (LLVMTypeRef ReturnType
,
1514 LLVMTypeRef ParamType1
,
1515 LLVMTypeRef ParamType2
,
1516 LLVMTypeRef ParamType3
,
1517 LLVMTypeRef ParamType4
,
1518 LLVMTypeRef ParamType5
,
1521 LLVMTypeRef param_types
[5];
1523 param_types
[0] = ParamType1
;
1524 param_types
[1] = ParamType2
;
1525 param_types
[2] = ParamType3
;
1526 param_types
[3] = ParamType4
;
1527 param_types
[4] = ParamType5
;
1529 return LLVMFunctionType (ReturnType
, param_types
, 5, IsVarArg
);
1535 * Create an LLVM builder and remember it so it can be freed later.
1537 static LLVMBuilderRef
1538 create_builder (EmitContext
*ctx
)
1540 LLVMBuilderRef builder
= LLVMCreateBuilder ();
1542 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
1548 get_aotconst_name (MonoJumpInfoType type
, gconstpointer data
, int got_offset
)
1553 case MONO_PATCH_INFO_INTERNAL_METHOD
:
1554 name
= g_strdup_printf ("jit_icall_%s", data
);
1556 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX
: {
1557 MonoJumpInfoRgctxEntry
*entry
= (MonoJumpInfoRgctxEntry
*)data
;
1558 name
= g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry
->info_type
));
1562 name
= g_strdup_printf ("%s_%d", mono_ji_type_to_string (type
), got_offset
);
1570 get_aotconst_typed (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
, LLVMTypeRef llvm_type
)
1574 LLVMValueRef indexes
[2];
1575 LLVMValueRef got_entry_addr
, load
;
1576 LLVMBuilderRef builder
= ctx
->builder
;
1581 MonoJumpInfo tmp_ji
;
1583 tmp_ji
.data
.target
= data
;
1585 MonoJumpInfo
*ji
= mono_aot_patch_info_dup (&tmp_ji
);
1587 ji
->next
= cfg
->patch_info
;
1588 cfg
->patch_info
= ji
;
1590 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
1591 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
1593 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1594 * explicitly initialize it.
1596 if (!mono_aot_is_shared_got_offset (got_offset
)) {
1597 //mono_print_ji (ji);
1599 ctx
->has_got_access
= TRUE
;
1602 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1603 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
1604 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
1606 name
= get_aotconst_name (type
, data
, got_offset
);
1608 load
= LLVMBuildLoad (builder
, got_entry_addr
, "");
1609 load
= convert (ctx
, load
, llvm_type
);
1610 LLVMSetValueName (load
, name
? name
: "");
1612 load
= LLVMBuildLoad (builder
, got_entry_addr
, name
? name
: "");
1615 //set_invariant_load_flag (load);
1621 get_aotconst (EmitContext
*ctx
, MonoJumpInfoType type
, gconstpointer data
)
1623 return get_aotconst_typed (ctx
, type
, data
, NULL
);
1627 get_callee (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
1629 LLVMValueRef callee
;
1631 if (ctx
->llvm_only
) {
1632 callee_name
= mono_aot_get_direct_call_symbol (type
, data
);
1634 /* Directly callable */
1636 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->direct_callables
, callee_name
);
1638 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1640 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1642 g_hash_table_insert (ctx
->module
->direct_callables
, (char*)callee_name
, callee
);
1644 /* LLVMTypeRef's are uniqued */
1645 if (LLVMGetElementType (LLVMTypeOf (callee
)) != llvm_sig
)
1646 return LLVMConstBitCast (callee
, LLVMPointerType (llvm_sig
, 0));
1648 g_free (callee_name
);
1654 * Calls are made through the GOT.
1656 return get_aotconst_typed (ctx
, type
, data
, LLVMPointerType (llvm_sig
, 0));
1658 MonoJumpInfo
*ji
= NULL
;
1660 callee_name
= mono_aot_get_plt_symbol (type
, data
);
1664 if (ctx
->cfg
->compile_aot
)
1665 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1666 mono_add_patch_info (ctx
->cfg
, 0, type
, data
);
1669 callee
= (LLVMValueRef
)g_hash_table_lookup (ctx
->module
->plt_entries
, callee_name
);
1671 callee
= LLVMAddFunction (ctx
->lmodule
, callee_name
, llvm_sig
);
1673 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
1675 g_hash_table_insert (ctx
->module
->plt_entries
, (char*)callee_name
, callee
);
1678 if (ctx
->cfg
->compile_aot
) {
1679 ji
= g_new0 (MonoJumpInfo
, 1);
1681 ji
->data
.target
= data
;
1683 g_hash_table_insert (ctx
->module
->plt_entries_ji
, ji
, callee
);
1691 emit_jit_callee (EmitContext
*ctx
, const char *name
, LLVMTypeRef llvm_sig
, gpointer target
)
1693 #if LLVM_API_VERSION > 100
1694 LLVMValueRef tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
1695 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
1696 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
1697 LLVMValueRef callee
= LLVMBuildLoad (ctx
->builder
, tramp_var
, "");
1700 LLVMValueRef callee
= LLVMAddFunction (ctx
->lmodule
, "", llvm_sig
);
1701 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
1707 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1709 MonoMethodHeader
*header
= cfg
->header
;
1710 MonoExceptionClause
*clause
;
1714 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1715 return (bb
->region
>> 8) - 1;
1718 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1719 clause
= &header
->clauses
[i
];
1721 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1728 static MonoExceptionClause
*
1729 get_most_deep_clause (MonoCompile
*cfg
, EmitContext
*ctx
, MonoBasicBlock
*bb
)
1731 // Since they're sorted by nesting we just need
1732 // the first one that the bb is a member of
1733 for (int i
= 0; i
< cfg
->header
->num_clauses
; i
++) {
1734 MonoExceptionClause
*curr
= &cfg
->header
->clauses
[i
];
1736 if (MONO_OFFSET_IN_CLAUSE (curr
, bb
->real_offset
))
1744 set_metadata_flag (LLVMValueRef v
, const char *flag_name
)
1746 LLVMValueRef md_arg
;
1749 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1750 md_arg
= LLVMMDString ("mono", 4);
1751 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1755 set_invariant_load_flag (LLVMValueRef v
)
1757 LLVMValueRef md_arg
;
1759 const char *flag_name
;
1761 // FIXME: Cache this
1762 flag_name
= "invariant.load";
1763 md_kind
= LLVMGetMDKindID (flag_name
, strlen (flag_name
));
1764 md_arg
= LLVMMDString ("<index>", strlen ("<index>"));
1765 LLVMSetMetadata (v
, md_kind
, LLVMMDNode (&md_arg
, 1));
1771 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1775 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1777 MonoCompile
*cfg
= ctx
->cfg
;
1778 LLVMValueRef lcall
= NULL
;
1779 LLVMBuilderRef builder
= *builder_ref
;
1780 MonoExceptionClause
*clause
;
1782 if (ctx
->llvm_only
) {
1783 clause
= get_most_deep_clause (cfg
, ctx
, bb
);
1786 g_assert (clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| clause
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1789 * Have to use an invoke instead of a call, branching to the
1790 * handler bblock of the clause containing this bblock.
1792 intptr_t key
= CLAUSE_END(clause
);
1794 LLVMBasicBlockRef lpad_bb
= (LLVMBasicBlockRef
)g_hash_table_lookup (ctx
->exc_meta
, (gconstpointer
)key
);
1796 // FIXME: Find the one that has the lowest end bound for the right start address
1797 // FIXME: Finally + nesting
1800 LLVMBasicBlockRef noex_bb
= gen_bb (ctx
, "CALL_NOEX_BB");
1803 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, lpad_bb
, "");
1805 builder
= ctx
->builder
= create_builder (ctx
);
1806 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1808 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1812 int clause_index
= get_handler_clause (cfg
, bb
);
1814 if (clause_index
!= -1) {
1815 MonoMethodHeader
*header
= cfg
->header
;
1816 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1817 MonoBasicBlock
*tblock
;
1818 LLVMBasicBlockRef ex_bb
, noex_bb
;
1821 * Have to use an invoke instead of a call, branching to the
1822 * handler bblock of the clause containing this bblock.
1825 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1827 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1830 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1832 ex_bb
= get_bb (ctx
, tblock
);
1834 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1837 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1839 builder
= ctx
->builder
= create_builder (ctx
);
1840 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1842 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1847 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1848 ctx
->builder
= builder
;
1852 *builder_ref
= ctx
->builder
;
1858 emit_load_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, LLVMValueRef base
, const char *name
, gboolean is_faulting
, BarrierKind barrier
)
1860 const char *intrins_name
;
1861 LLVMValueRef args
[16], res
;
1862 LLVMTypeRef addr_type
;
1863 gboolean use_intrinsics
= TRUE
;
1865 #if LLVM_API_VERSION > 100
1866 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
1867 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1870 cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
1871 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
1872 *builder_ref
= ctx
->builder
;
1873 use_intrinsics
= FALSE
;
1877 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
1878 LLVMAtomicOrdering ordering
;
1881 case LLVM_BARRIER_NONE
:
1882 ordering
= LLVMAtomicOrderingNotAtomic
;
1884 case LLVM_BARRIER_ACQ
:
1885 ordering
= LLVMAtomicOrderingAcquire
;
1887 case LLVM_BARRIER_SEQ
:
1888 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
1891 g_assert_not_reached ();
1896 * We handle loads which can fault by calling a mono specific intrinsic
1897 * using an invoke, so they are handled properly inside try blocks.
1898 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1899 * are marked with IntrReadArgMem.
1903 intrins_name
= "llvm.mono.load.i8.p0i8";
1906 intrins_name
= "llvm.mono.load.i16.p0i16";
1909 intrins_name
= "llvm.mono.load.i32.p0i32";
1912 intrins_name
= "llvm.mono.load.i64.p0i64";
1915 g_assert_not_reached ();
1918 addr_type
= LLVMTypeOf (addr
);
1919 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0) || addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1920 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
1923 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1924 args
[2] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
1925 args
[3] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
1926 res
= emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 4);
1928 if (addr_type
== LLVMPointerType (LLVMDoubleType (), 0))
1929 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMDoubleType (), "");
1930 else if (addr_type
== LLVMPointerType (LLVMFloatType (), 0))
1931 res
= LLVMBuildBitCast (*builder_ref
, res
, LLVMFloatType (), "");
1938 * We emit volatile loads for loads which can fault, because otherwise
1939 * LLVM will generate invalid code when encountering a load from a
1942 if (barrier
!= LLVM_BARRIER_NONE
)
1943 res
= mono_llvm_build_atomic_load (*builder_ref
, addr
, name
, is_faulting
, size
, barrier
);
1945 res
= mono_llvm_build_load (*builder_ref
, addr
, name
, is_faulting
);
1947 /* Mark it with a custom metadata */
1950 set_metadata_flag (res, "mono.faulting.load");
1958 emit_load (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef addr
, const char *name
, gboolean is_faulting
)
1960 return emit_load_general (ctx
, bb
, builder_ref
, size
, addr
, addr
, name
, is_faulting
, LLVM_BARRIER_NONE
);
1964 emit_store_general (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
, BarrierKind barrier
)
1966 const char *intrins_name
;
1967 LLVMValueRef args
[16];
1968 gboolean use_intrinsics
= TRUE
;
1970 #if LLVM_API_VERSION > 100
1971 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
) {
1972 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1973 LLVMValueRef cmp
= LLVMBuildICmp (*builder_ref
, LLVMIntEQ
, base
, LLVMConstNull (LLVMTypeOf (base
)), "");
1974 emit_cond_system_exception (ctx
, bb
, "NullReferenceException", cmp
);
1975 *builder_ref
= ctx
->builder
;
1976 use_intrinsics
= FALSE
;
1980 if (is_faulting
&& bb
->region
!= -1 && !ctx
->cfg
->llvm_only
&& use_intrinsics
) {
1981 LLVMAtomicOrdering ordering
;
1984 case LLVM_BARRIER_NONE
:
1985 ordering
= LLVMAtomicOrderingNotAtomic
;
1987 case LLVM_BARRIER_REL
:
1988 ordering
= LLVMAtomicOrderingRelease
;
1990 case LLVM_BARRIER_SEQ
:
1991 ordering
= LLVMAtomicOrderingSequentiallyConsistent
;
1994 g_assert_not_reached ();
2000 intrins_name
= "llvm.mono.store.i8.p0i8";
2003 intrins_name
= "llvm.mono.store.i16.p0i16";
2006 intrins_name
= "llvm.mono.store.i32.p0i32";
2009 intrins_name
= "llvm.mono.store.i64.p0i64";
2012 g_assert_not_reached ();
2015 if (LLVMTypeOf (value
) == LLVMDoubleType () || LLVMTypeOf (value
) == LLVMFloatType ()) {
2016 value
= LLVMBuildBitCast (*builder_ref
, value
, LLVMIntType (size
* 8), "");
2017 addr
= LLVMBuildBitCast (*builder_ref
, addr
, LLVMPointerType (LLVMIntType (size
* 8), 0), "");
2022 args
[2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2023 args
[3] = LLVMConstInt (LLVMInt1Type (), TRUE
, FALSE
);
2024 args
[4] = LLVMConstInt (LLVMInt32Type (), ordering
, FALSE
);
2025 emit_call (ctx
, bb
, builder_ref
, get_intrinsic (ctx
, intrins_name
), args
, 5);
2027 if (barrier
!= LLVM_BARRIER_NONE
)
2028 mono_llvm_build_aligned_store (*builder_ref
, value
, addr
, barrier
, size
);
2030 mono_llvm_build_store (*builder_ref
, value
, addr
, is_faulting
, barrier
);
2035 emit_store (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, int size
, LLVMValueRef value
, LLVMValueRef addr
, LLVMValueRef base
, gboolean is_faulting
)
2037 emit_store_general (ctx
, bb
, builder_ref
, size
, value
, addr
, base
, is_faulting
, LLVM_BARRIER_NONE
);
2041 * emit_cond_system_exception:
2043 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2044 * Might set the ctx exception.
2047 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
2049 LLVMBasicBlockRef ex_bb
, ex2_bb
= NULL
, noex_bb
;
2050 LLVMBuilderRef builder
;
2051 MonoClass
*exc_class
;
2052 LLVMValueRef args
[2];
2053 LLVMValueRef callee
;
2054 gboolean no_pc
= FALSE
;
2056 if (IS_TARGET_AMD64
)
2057 /* Some platforms don't require the pc argument */
2060 ex_bb
= gen_bb (ctx
, "EX_BB");
2062 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2063 noex_bb
= gen_bb (ctx
, "NOEX_BB");
2065 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
2067 exc_class
= mono_class_load_from_name (mono_get_corlib (), "System", exc_type
);
2069 /* Emit exception throwing code */
2070 ctx
->builder
= builder
= create_builder (ctx
);
2071 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
2073 if (ctx
->cfg
->llvm_only
) {
2074 static LLVMTypeRef sig
;
2077 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2078 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, "mono_llvm_throw_corlib_exception");
2080 LLVMBuildBr (builder
, ex2_bb
);
2082 ctx
->builder
= builder
= create_builder (ctx
);
2083 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2085 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2086 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2087 LLVMBuildUnreachable (builder
);
2089 ctx
->builder
= builder
= create_builder (ctx
);
2090 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2092 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2098 callee
= ctx
->module
->throw_corlib_exception
;
2101 const char *icall_name
;
2104 sig
= LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
);
2106 sig
= LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE
);
2107 icall_name
= "llvm_throw_corlib_exception_abs_trampoline";
2109 if (ctx
->cfg
->compile_aot
) {
2110 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2113 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2114 * - On x86, LLVM generated code doesn't push the arguments
2115 * - The trampoline takes the throw address as an arguments, not a pc offset.
2117 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
2118 callee
= emit_jit_callee (ctx
, "llvm_throw_corlib_exception_trampoline", sig
, target
);
2120 #if LLVM_API_VERSION > 100
2122 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2123 * added by emit_jit_callee ().
2125 ex2_bb
= gen_bb (ctx
, "EX2_BB");
2126 LLVMBuildBr (builder
, ex2_bb
);
2129 ctx
->builder
= builder
= create_builder (ctx
);
2130 LLVMPositionBuilderAtEnd (ctx
->builder
, ex2_bb
);
2132 mono_memory_barrier ();
2133 ctx
->module
->throw_corlib_exception
= callee
;
2138 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
2141 * The LLVM mono branch contains changes so a block address can be passed as an
2142 * argument to a call.
2145 emit_call (ctx
, bb
, &builder
, callee
, args
, 1);
2147 args
[1] = LLVMBlockAddress (ctx
->lmethod
, ex_bb
);
2148 emit_call (ctx
, bb
, &builder
, callee
, args
, 2);
2151 LLVMBuildUnreachable (builder
);
2153 ctx
->builder
= builder
= create_builder (ctx
);
2154 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
2156 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
2163 * emit_args_to_vtype:
2165 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2168 emit_args_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
)
2170 int j
, size
, nslots
;
2172 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
2174 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2175 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2178 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2179 nslots
= ainfo
->nslots
;
2183 for (j
= 0; j
< nslots
; ++j
) {
2184 LLVMValueRef index
[2], addr
, daddr
;
2185 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2186 LLVMTypeRef part_type
;
2188 while (part_size
!= 1 && part_size
!= 2 && part_size
!= 4 && part_size
< 8)
2191 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2194 switch (ainfo
->pair_storage
[j
]) {
2195 case LLVMArgInIReg
: {
2196 part_type
= LLVMIntType (part_size
* 8);
2197 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2198 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2199 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2201 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2202 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2203 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2205 LLVMBuildStore (builder
, convert (ctx
, args
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
2208 case LLVMArgInFPReg
: {
2209 LLVMTypeRef arg_type
;
2211 if (ainfo
->esize
== 8)
2212 arg_type
= LLVMDoubleType ();
2214 arg_type
= LLVMFloatType ();
2216 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2217 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2218 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2219 LLVMBuildStore (builder
, args
[j
], addr
);
2225 g_assert_not_reached ();
2228 size
-= sizeof (gpointer
);
2233 * emit_vtype_to_args:
2235 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2236 * into ARGS, and the number of arguments into NARGS.
2239 emit_vtype_to_args (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*args
, guint32
*nargs
)
2242 int j
, size
, nslots
;
2243 LLVMTypeRef arg_type
;
2245 size
= get_vtype_size (t
);
2247 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
)))
2248 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
2250 if (ainfo
->storage
== LLVMArgAsFpArgs
)
2251 nslots
= ainfo
->nslots
;
2254 for (j
= 0; j
< nslots
; ++j
) {
2255 LLVMValueRef index
[2], addr
, daddr
;
2256 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
2258 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
2261 switch (ainfo
->pair_storage
[j
]) {
2263 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
2264 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
2265 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
2267 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (IntPtrType (), 0), "");
2268 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2269 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2271 args
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
2273 case LLVMArgInFPReg
:
2274 if (ainfo
->esize
== 8)
2275 arg_type
= LLVMDoubleType ();
2277 arg_type
= LLVMFloatType ();
2278 daddr
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (arg_type
, 0), "");
2279 index
[0] = LLVMConstInt (LLVMInt32Type (), j
, FALSE
);
2280 addr
= LLVMBuildGEP (builder
, daddr
, index
, 1, "");
2281 args
[pindex
++] = LLVMBuildLoad (builder
, addr
, "");
2286 g_assert_not_reached ();
2288 size
-= sizeof (gpointer
);
2295 build_alloca_llvm_type_name (EmitContext
*ctx
, LLVMTypeRef t
, int align
, const char *name
)
2298 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2299 * get executed every time control reaches them.
2301 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
2303 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, t
, NULL
, align
, name
);
2304 return ctx
->last_alloca
;
2308 build_alloca_llvm_type (EmitContext
*ctx
, LLVMTypeRef t
, int align
)
2310 return build_alloca_llvm_type_name (ctx
, t
, align
, "");
2314 build_alloca (EmitContext
*ctx
, MonoType
*t
)
2316 MonoClass
*k
= mono_class_from_mono_type (t
);
2319 g_assert (!mini_is_gsharedvt_variable_type (t
));
2321 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
2324 align
= mono_class_min_align (k
);
2326 /* Sometimes align is not a power of 2 */
2327 while (mono_is_power_of_two (align
) == -1)
2330 return build_alloca_llvm_type (ctx
, type_to_llvm_type (ctx
, t
), align
);
2334 emit_gsharedvt_ldaddr (EmitContext
*ctx
, int vreg
)
2338 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2340 MonoCompile
*cfg
= ctx
->cfg
;
2341 LLVMBuilderRef builder
= ctx
->builder
;
2342 LLVMValueRef offset
, offset_var
;
2343 LLVMValueRef info_var
= ctx
->values
[cfg
->gsharedvt_info_var
->dreg
];
2344 LLVMValueRef locals_var
= ctx
->values
[cfg
->gsharedvt_locals_var
->dreg
];
2348 g_assert (info_var
);
2349 g_assert (locals_var
);
2351 int idx
= cfg
->gsharedvt_vreg_to_idx
[vreg
] - 1;
2353 offset
= LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo
, entries
) + (idx
* sizeof (gpointer
)), FALSE
);
2354 ptr
= LLVMBuildAdd (builder
, convert (ctx
, info_var
, IntPtrType ()), convert (ctx
, offset
, IntPtrType ()), "");
2356 name
= g_strdup_printf ("gsharedvt_local_%d_offset", vreg
);
2357 offset_var
= LLVMBuildLoad (builder
, convert (ctx
, ptr
, LLVMPointerType (LLVMInt32Type (), 0)), name
);
2359 return LLVMBuildAdd (builder
, convert (ctx
, locals_var
, IntPtrType ()), convert (ctx
, offset_var
, IntPtrType ()), "");
2363 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2366 mark_as_used (MonoLLVMModule
*module
, LLVMValueRef global
)
2369 module
->used
= g_ptr_array_sized_new (16);
2370 g_ptr_array_add (module
->used
, global
);
2374 emit_llvm_used (MonoLLVMModule
*module
)
2376 LLVMModuleRef lmodule
= module
->lmodule
;
2377 LLVMTypeRef used_type
;
2378 LLVMValueRef used
, *used_elem
;
2384 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module
->used
->len
);
2385 used
= LLVMAddGlobal (lmodule
, used_type
, "llvm.used");
2386 used_elem
= g_new0 (LLVMValueRef
, module
->used
->len
);
2387 for (i
= 0; i
< module
->used
->len
; ++i
)
2388 used_elem
[i
] = LLVMConstBitCast ((LLVMValueRef
)g_ptr_array_index (module
->used
, i
), LLVMPointerType (LLVMInt8Type (), 0));
2389 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem
, module
->used
->len
));
2390 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
2391 LLVMSetSection (used
, "llvm.metadata");
2397 * Emit a function mapping method indexes to their code
2400 emit_get_method (MonoLLVMModule
*module
)
2402 LLVMModuleRef lmodule
= module
->lmodule
;
2403 LLVMValueRef func
, switch_ins
, m
;
2404 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
, code_start_bb
, code_end_bb
;
2405 LLVMBasicBlockRef
*bbs
;
2407 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2412 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2413 * but generating code seems safer.
2415 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2416 func
= LLVMAddFunction (lmodule
, module
->get_method_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2417 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2418 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2419 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2420 module
->get_method
= func
;
2422 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2425 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2426 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2427 * then we will have to find another solution.
2430 name
= g_strdup_printf ("BB_CODE_START");
2431 code_start_bb
= LLVMAppendBasicBlock (func
, name
);
2433 LLVMPositionBuilderAtEnd (builder
, code_start_bb
);
2434 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_start
, rtype
, ""));
2436 name
= g_strdup_printf ("BB_CODE_END");
2437 code_end_bb
= LLVMAppendBasicBlock (func
, name
);
2439 LLVMPositionBuilderAtEnd (builder
, code_end_bb
);
2440 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, module
->code_end
, rtype
, ""));
2442 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2443 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2444 name
= g_strdup_printf ("BB_%d", i
);
2445 bb
= LLVMAppendBasicBlock (func
, name
);
2449 LLVMPositionBuilderAtEnd (builder
, bb
);
2451 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_lmethod
, GINT_TO_POINTER (i
));
2453 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2455 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2458 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2459 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2460 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2462 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2464 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2465 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -1, FALSE
), code_start_bb
);
2466 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), -2, FALSE
), code_end_bb
);
2467 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2468 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2471 mark_as_used (module
, func
);
2473 LLVMDisposeBuilder (builder
);
2477 * emit_get_unbox_tramp:
2479 * Emit a function mapping method indexes to their unbox trampoline
2482 emit_get_unbox_tramp (MonoLLVMModule
*module
)
2484 LLVMModuleRef lmodule
= module
->lmodule
;
2485 LLVMValueRef func
, switch_ins
, m
;
2486 LLVMBasicBlockRef entry_bb
, fail_bb
, bb
;
2487 LLVMBasicBlockRef
*bbs
;
2489 LLVMBuilderRef builder
= LLVMCreateBuilder ();
2493 /* Similar to emit_get_method () */
2495 rtype
= LLVMPointerType (LLVMInt8Type (), 0);
2496 func
= LLVMAddFunction (lmodule
, module
->get_unbox_tramp_symbol
, LLVMFunctionType1 (rtype
, LLVMInt32Type (), FALSE
));
2497 LLVMSetLinkage (func
, LLVMExternalLinkage
);
2498 LLVMSetVisibility (func
, LLVMHiddenVisibility
);
2499 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2500 module
->get_unbox_tramp
= func
;
2502 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2504 bbs
= g_new0 (LLVMBasicBlockRef
, module
->max_method_idx
+ 1);
2505 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2506 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2510 name
= g_strdup_printf ("BB_%d", i
);
2511 bb
= LLVMAppendBasicBlock (func
, name
);
2515 LLVMPositionBuilderAtEnd (builder
, bb
);
2517 LLVMBuildRet (builder
, LLVMBuildBitCast (builder
, m
, rtype
, ""));
2520 fail_bb
= LLVMAppendBasicBlock (func
, "FAIL");
2521 LLVMPositionBuilderAtEnd (builder
, fail_bb
);
2522 LLVMBuildRet (builder
, LLVMConstNull (rtype
));
2524 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2526 switch_ins
= LLVMBuildSwitch (builder
, LLVMGetParam (func
, 0), fail_bb
, 0);
2527 for (i
= 0; i
< module
->max_method_idx
+ 1; ++i
) {
2528 m
= (LLVMValueRef
)g_hash_table_lookup (module
->idx_to_unbox_tramp
, GINT_TO_POINTER (i
));
2532 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), bbs
[i
]);
2535 mark_as_used (module
, func
);
2536 LLVMDisposeBuilder (builder
);
2539 /* Add a function to mark the beginning of LLVM code */
2541 emit_llvm_code_start (MonoLLVMModule
*module
)
2543 LLVMModuleRef lmodule
= module
->lmodule
;
2545 LLVMBasicBlockRef entry_bb
;
2546 LLVMBuilderRef builder
;
2548 func
= LLVMAddFunction (lmodule
, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2549 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2550 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2551 module
->code_start
= func
;
2552 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2553 builder
= LLVMCreateBuilder ();
2554 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2555 LLVMBuildRetVoid (builder
);
2556 LLVMDisposeBuilder (builder
);
2560 emit_init_icall_wrapper (MonoLLVMModule
*module
, const char *name
, const char *icall_name
, int subtype
)
2562 LLVMModuleRef lmodule
= module
->lmodule
;
2563 LLVMValueRef func
, indexes
[2], got_entry_addr
, args
[16], callee
;
2564 LLVMBasicBlockRef entry_bb
;
2565 LLVMBuilderRef builder
;
2572 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE
));
2573 sig
= LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE
);
2578 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE
));
2579 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE
);
2582 func
= LLVMAddFunction (lmodule
, name
, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE
));
2583 sig
= LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE
);
2586 g_assert_not_reached ();
2588 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2589 LLVMAddFunctionAttr (func
, LLVMNoInlineAttribute
);
2590 mono_llvm_set_preserveall_cc (func
);
2591 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2592 builder
= LLVMCreateBuilder ();
2593 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2596 ji
= g_new0 (MonoJumpInfo
, 1);
2597 ji
->type
= MONO_PATCH_INFO_AOT_MODULE
;
2598 ji
= mono_aot_patch_info_dup (ji
);
2599 got_offset
= mono_aot_get_got_offset (ji
);
2600 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2601 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2602 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2603 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2604 args
[0] = LLVMBuildPtrToInt (builder
, LLVMBuildLoad (builder
, got_entry_addr
, ""), IntPtrType (), "");
2605 args
[1] = LLVMGetParam (func
, 0);
2607 args
[2] = LLVMGetParam (func
, 1);
2609 ji
= g_new0 (MonoJumpInfo
, 1);
2610 ji
->type
= MONO_PATCH_INFO_INTERNAL_METHOD
;
2611 ji
->data
.name
= icall_name
;
2612 ji
= mono_aot_patch_info_dup (ji
);
2613 got_offset
= mono_aot_get_got_offset (ji
);
2614 module
->max_got_offset
= MAX (module
->max_got_offset
, got_offset
);
2615 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2616 indexes
[1] = LLVMConstInt (LLVMInt32Type (), got_offset
, FALSE
);
2617 got_entry_addr
= LLVMBuildGEP (builder
, module
->got_var
, indexes
, 2, "");
2618 callee
= LLVMBuildLoad (builder
, got_entry_addr
, "");
2619 callee
= LLVMBuildBitCast (builder
, callee
, LLVMPointerType (sig
, 0), "");
2620 LLVMBuildCall (builder
, callee
, args
, LLVMCountParamTypes (sig
), "");
2622 // Set the inited flag
2623 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2624 indexes
[1] = LLVMGetParam (func
, 0);
2625 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt8Type (), 1, FALSE
), LLVMBuildGEP (builder
, module
->inited_var
, indexes
, 2, ""));
2627 LLVMBuildRetVoid (builder
);
2629 LLVMVerifyFunction(func
, LLVMAbortProcessAction
);
2630 LLVMDisposeBuilder (builder
);
2635 * Emit wrappers around the C icalls used to initialize llvm methods, to
2636 * make the calling code smaller and to enable usage of the llvm
2637 * PreserveAll calling convention.
2640 emit_init_icall_wrappers (MonoLLVMModule
*module
)
2642 module
->init_method
= emit_init_icall_wrapper (module
, "init_method", "mono_aot_init_llvm_method", 0);
2643 module
->init_method_gshared_mrgctx
= emit_init_icall_wrapper (module
, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2644 module
->init_method_gshared_this
= emit_init_icall_wrapper (module
, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2645 module
->init_method_gshared_vtable
= emit_init_icall_wrapper (module
, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2649 emit_llvm_code_end (MonoLLVMModule
*module
)
2651 LLVMModuleRef lmodule
= module
->lmodule
;
2653 LLVMBasicBlockRef entry_bb
;
2654 LLVMBuilderRef builder
;
2656 func
= LLVMAddFunction (lmodule
, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
2657 LLVMSetLinkage (func
, LLVMInternalLinkage
);
2658 LLVMAddFunctionAttr (func
, LLVMNoUnwindAttribute
);
2659 module
->code_end
= func
;
2660 entry_bb
= LLVMAppendBasicBlock (func
, "ENTRY");
2661 builder
= LLVMCreateBuilder ();
2662 LLVMPositionBuilderAtEnd (builder
, entry_bb
);
2663 LLVMBuildRetVoid (builder
);
2664 LLVMDisposeBuilder (builder
);
2668 emit_div_check (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoBasicBlock
*bb
, MonoInst
*ins
, LLVMValueRef lhs
, LLVMValueRef rhs
)
2670 gboolean need_div_check
= ctx
->cfg
->backend
->need_div_check
;
2673 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2674 need_div_check
= TRUE
;
2676 if (!need_div_check
)
2679 switch (ins
->opcode
) {
2692 case OP_IDIV_UN_IMM
:
2693 case OP_LDIV_UN_IMM
:
2694 case OP_IREM_UN_IMM
:
2695 case OP_LREM_UN_IMM
: {
2697 gboolean is_signed
= (ins
->opcode
== OP_IDIV
|| ins
->opcode
== OP_LDIV
|| ins
->opcode
== OP_IREM
|| ins
->opcode
== OP_LREM
||
2698 ins
->opcode
== OP_IDIV_IMM
|| ins
->opcode
== OP_LDIV_IMM
|| ins
->opcode
== OP_IREM_IMM
|| ins
->opcode
== OP_LREM_IMM
);
2700 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), 0, FALSE
), "");
2701 emit_cond_system_exception (ctx
, bb
, "DivideByZeroException", cmp
);
2704 builder
= ctx
->builder
;
2706 /* b == -1 && a == 0x80000000 */
2708 LLVMValueRef c
= (LLVMTypeOf (lhs
) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs
), 0x80000000, FALSE
) : LLVMConstInt (LLVMTypeOf (lhs
), 0x8000000000000000LL
, FALSE
);
2709 LLVMValueRef cond1
= LLVMBuildICmp (builder
, LLVMIntEQ
, rhs
, LLVMConstInt (LLVMTypeOf (rhs
), -1, FALSE
), "");
2710 LLVMValueRef cond2
= LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, c
, "");
2712 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, LLVMBuildAnd (builder
, cond1
, cond2
, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE
), "");
2713 emit_cond_system_exception (ctx
, bb
, "OverflowException", cmp
);
2716 builder
= ctx
->builder
;
2728 * Emit code to initialize the GOT slots used by the method.
2731 emit_init_method (EmitContext
*ctx
)
2733 LLVMValueRef indexes
[16], args
[16], callee
;
2734 LLVMValueRef inited_var
, cmp
, call
;
2735 LLVMBasicBlockRef inited_bb
, notinited_bb
;
2736 LLVMBuilderRef builder
= ctx
->builder
;
2737 MonoCompile
*cfg
= ctx
->cfg
;
2739 ctx
->module
->max_inited_idx
= MAX (ctx
->module
->max_inited_idx
, cfg
->method_index
);
2741 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2742 indexes
[1] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, FALSE
);
2743 inited_var
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, ctx
->module
->inited_var
, indexes
, 2, ""), "is_inited");
2745 args
[0] = inited_var
;
2746 args
[1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE
);
2747 inited_var
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i8"), args
, 2, "");
2749 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, inited_var
, LLVMConstInt (LLVMTypeOf (inited_var
), 0, FALSE
), "");
2751 inited_bb
= ctx
->inited_bb
;
2752 notinited_bb
= gen_bb (ctx
, "NOTINITED_BB");
2754 LLVMBuildCondBr (ctx
->builder
, cmp
, notinited_bb
, inited_bb
);
2756 builder
= ctx
->builder
= create_builder (ctx
);
2757 LLVMPositionBuilderAtEnd (ctx
->builder
, notinited_bb
);
2760 if (ctx
->rgctx_arg
&& cfg
->method
->is_inflated
&& mono_method_get_context (cfg
->method
)->method_inst
) {
2761 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2762 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2763 callee
= ctx
->module
->init_method_gshared_mrgctx
;
2764 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2765 } else if (ctx
->rgctx_arg
) {
2766 /* A vtable is passed as the rgctx argument */
2767 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2768 args
[1] = convert (ctx
, ctx
->rgctx_arg
, IntPtrType ());
2769 callee
= ctx
->module
->init_method_gshared_vtable
;
2770 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2771 } else if (cfg
->gshared
) {
2772 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2773 args
[1] = convert (ctx
, ctx
->this_arg
, ObjRefType ());
2774 callee
= ctx
->module
->init_method_gshared_this
;
2775 call
= LLVMBuildCall (builder
, callee
, args
, 2, "");
2777 args
[0] = LLVMConstInt (LLVMInt32Type (), cfg
->method_index
, 0);
2778 callee
= ctx
->module
->init_method
;
2779 call
= LLVMBuildCall (builder
, callee
, args
, 1, "");
2783 * This enables llvm to keep arguments in their original registers/
2784 * scratch registers, since the call will not clobber them.
2786 mono_llvm_set_call_preserveall_cc (call
);
2788 LLVMBuildBr (builder
, inited_bb
);
2789 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= inited_bb
;
2791 builder
= ctx
->builder
= create_builder (ctx
);
2792 LLVMPositionBuilderAtEnd (ctx
->builder
, inited_bb
);
2796 emit_unbox_tramp (EmitContext
*ctx
, const char *method_name
, LLVMTypeRef method_type
, LLVMValueRef method
, int method_index
)
2799 * Emit unbox trampoline using a tail call
2801 LLVMValueRef tramp
, call
, *args
;
2802 LLVMBuilderRef builder
;
2803 LLVMBasicBlockRef lbb
;
2804 LLVMCallInfo
*linfo
;
2808 tramp_name
= g_strdup_printf ("ut_%s", method_name
);
2809 tramp
= LLVMAddFunction (ctx
->module
->lmodule
, tramp_name
, method_type
);
2810 LLVMSetLinkage (tramp
, LLVMInternalLinkage
);
2811 LLVMAddFunctionAttr (tramp
, LLVMOptimizeForSizeAttribute
);
2812 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2814 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2815 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2816 LLVMAddAttribute (LLVMGetParam (tramp
, ctx
->rgctx_arg_pindex
), LLVMInRegAttribute
);
2817 if (ctx
->cfg
->vret_addr
) {
2818 LLVMSetValueName (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), "vret");
2819 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
2820 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
2821 LLVMAddAttribute (LLVMGetParam (tramp
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
2825 lbb
= LLVMAppendBasicBlock (tramp
, "");
2826 builder
= LLVMCreateBuilder ();
2827 LLVMPositionBuilderAtEnd (builder
, lbb
);
2829 nargs
= LLVMCountParamTypes (method_type
);
2830 args
= g_new0 (LLVMValueRef
, nargs
);
2831 for (i
= 0; i
< nargs
; ++i
) {
2832 args
[i
] = LLVMGetParam (tramp
, i
);
2833 if (i
== ctx
->this_arg_pindex
) {
2834 LLVMTypeRef arg_type
= LLVMTypeOf (args
[i
]);
2836 args
[i
] = LLVMBuildPtrToInt (builder
, args
[i
], IntPtrType (), "");
2837 args
[i
] = LLVMBuildAdd (builder
, args
[i
], LLVMConstInt (IntPtrType (), sizeof (MonoObject
), FALSE
), "");
2838 args
[i
] = LLVMBuildIntToPtr (builder
, args
[i
], arg_type
, "");
2841 call
= LLVMBuildCall (builder
, method
, args
, nargs
, "");
2842 if (!ctx
->llvm_only
&& ctx
->rgctx_arg_pindex
!= -1)
2843 LLVMAddInstrAttribute (call
, 1 + ctx
->rgctx_arg_pindex
, LLVMInRegAttribute
);
2844 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
)
2845 LLVMAddInstrAttribute (call
, 1 + linfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
2847 // FIXME: This causes assertions in clang
2848 //mono_llvm_set_must_tail (call);
2849 if (LLVMGetReturnType (method_type
) == LLVMVoidType ())
2850 LLVMBuildRetVoid (builder
);
2852 LLVMBuildRet (builder
, call
);
2854 g_hash_table_insert (ctx
->module
->idx_to_unbox_tramp
, GINT_TO_POINTER (method_index
), tramp
);
2855 LLVMDisposeBuilder (builder
);
2861 * Emit code to load/convert arguments.
2864 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
)
2867 MonoCompile
*cfg
= ctx
->cfg
;
2868 MonoMethodSignature
*sig
= ctx
->sig
;
2869 LLVMCallInfo
*linfo
= ctx
->linfo
;
2873 LLVMBuilderRef old_builder
= ctx
->builder
;
2874 ctx
->builder
= builder
;
2876 ctx
->alloca_builder
= create_builder (ctx
);
2879 * Handle indirect/volatile variables by allocating memory for them
2880 * using 'alloca', and storing their address in a temporary.
2882 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
2883 MonoInst
*var
= cfg
->varinfo
[i
];
2886 if (var
->opcode
== OP_GSHAREDVT_LOCAL
|| var
->opcode
== OP_GSHAREDVT_ARG_REGOFFSET
) {
2887 } 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
))) {
2888 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
2891 /* Could be already created by an OP_VPHI */
2892 if (!ctx
->addresses
[var
->dreg
]) {
2893 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
2894 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2896 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
2900 names
= g_new (char *, sig
->param_count
);
2901 mono_method_get_param_names (cfg
->method
, (const char **) names
);
2903 for (i
= 0; i
< sig
->param_count
; ++i
) {
2904 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
2905 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
2908 pindex
= ainfo
->pindex
;
2910 switch (ainfo
->storage
) {
2911 case LLVMArgVtypeInReg
:
2912 case LLVMArgAsFpArgs
: {
2913 LLVMValueRef args
[8];
2916 pindex
+= ainfo
->ndummy_fpargs
;
2918 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2919 memset (args
, 0, sizeof (args
));
2920 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2921 args
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
2922 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
2923 args
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
2925 g_assert (ainfo
->nslots
<= 8);
2926 for (j
= 0; j
< ainfo
->nslots
; ++j
)
2927 args
[j
] = LLVMGetParam (ctx
->lmethod
, pindex
+ j
);
2929 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
2931 emit_args_to_vtype (ctx
, builder
, ainfo
->type
, ctx
->addresses
[reg
], ainfo
, args
);
2933 if (ainfo
->storage
== LLVMArgVtypeInReg
&& MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2934 /* Treat these as normal values */
2935 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2939 case LLVMArgVtypeByVal
: {
2940 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
2942 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (ainfo
->type
))) {
2943 /* Treat these as normal values */
2944 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
2948 case LLVMArgVtypeByRef
: {
2949 /* The argument is passed by ref */
2950 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
2953 case LLVMArgAsIArgs
: {
2954 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
2957 /* The argument is received as an array of ints, store it into the real argument */
2958 ctx
->addresses
[reg
] = build_alloca (ctx
, ainfo
->type
);
2960 size
= mono_class_value_size (mono_class_from_mono_type (ainfo
->type
), NULL
);
2961 if (size
< SIZEOF_VOID_P
) {
2962 /* The upper bits of the registers might not be valid */
2963 LLVMValueRef val
= LLVMBuildExtractValue (builder
, arg
, 0, "");
2964 LLVMValueRef dest
= convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMIntType (size
* 8), 0));
2965 LLVMBuildStore (ctx
->builder
, LLVMBuildTrunc (builder
, val
, LLVMIntType (size
* 8), ""), dest
);
2967 LLVMBuildStore (ctx
->builder
, arg
, convert (ctx
, ctx
->addresses
[reg
], LLVMPointerType (LLVMTypeOf (arg
), 0)));
2971 case LLVMArgVtypeAsScalar
:
2972 g_assert_not_reached ();
2974 case LLVMArgGsharedvtFixed
: {
2975 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2976 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
2979 name
= g_strdup_printf ("arg_%s", names
[i
]);
2981 name
= g_strdup_printf ("arg_%d", i
);
2983 ctx
->values
[reg
] = LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), name
);
2986 case LLVMArgGsharedvtFixedVtype
: {
2987 LLVMValueRef arg
= LLVMGetParam (ctx
->lmethod
, pindex
);
2990 name
= g_strdup_printf ("vtype_arg_%s", names
[i
]);
2992 name
= g_strdup_printf ("vtype_arg_%d", i
);
2994 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2995 g_assert (ctx
->addresses
[reg
]);
2996 LLVMSetValueName (ctx
->addresses
[reg
], name
);
2997 LLVMBuildStore (builder
, LLVMBuildLoad (builder
, convert (ctx
, arg
, LLVMPointerType (type_to_llvm_type (ctx
, ainfo
->type
), 0)), ""), ctx
->addresses
[reg
]);
3000 case LLVMArgGsharedvtVariable
:
3001 /* The IR treats these as variables with addresses */
3002 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindex
);
3005 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
));
3012 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
3014 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
3015 for (i
= 0; i
< sig
->param_count
; ++i
)
3016 if (!mini_type_is_vtype (sig
->params
[i
]))
3017 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
3019 if (sig
->hasthis
&& !cfg
->rgctx_var
&& cfg
->gshared
) {
3020 LLVMValueRef this_alloc
;
3023 * The exception handling code needs the location where the this argument was
3024 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3025 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3026 * location into the LSDA.
3028 this_alloc
= mono_llvm_build_alloca (builder
, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
3029 /* This volatile store will keep the alloca alive */
3030 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3032 set_metadata_flag (this_alloc
, "mono.this");
3035 if (cfg
->rgctx_var
) {
3036 LLVMValueRef rgctx_alloc
, store
;
3039 * We handle the rgctx arg similarly to the this pointer.
3041 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
3042 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
3043 /* This volatile store will keep the alloca alive */
3044 store
= mono_llvm_build_store (builder
, convert (ctx
, ctx
->rgctx_arg
, IntPtrType ()), rgctx_alloc
, TRUE
, LLVM_BARRIER_NONE
);
3046 set_metadata_flag (rgctx_alloc
, "mono.this");
3049 /* Initialize the method if needed */
3050 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
3051 /* Emit a location for the initialization code */
3052 ctx
->init_bb
= gen_bb (ctx
, "INIT_BB");
3053 ctx
->inited_bb
= gen_bb (ctx
, "INITED_BB");
3055 LLVMBuildBr (ctx
->builder
, ctx
->init_bb
);
3056 builder
= ctx
->builder
= create_builder (ctx
);
3057 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->inited_bb
);
3058 ctx
->bblocks
[cfg
->bb_entry
->block_num
].end_bblock
= ctx
->inited_bb
;
3061 /* Compute nesting between clauses */
3062 ctx
->nested_in
= (GSList
**)mono_mempool_alloc0 (cfg
->mempool
, sizeof (GSList
*) * cfg
->header
->num_clauses
);
3063 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
3064 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
3065 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
3066 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
3068 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
)
3069 ctx
->nested_in
[i
] = g_slist_prepend_mempool (cfg
->mempool
, ctx
->nested_in
[i
], GINT_TO_POINTER (j
));
3074 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3075 * it needs to continue normally, or return back to the exception handling system.
3077 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3081 if (!(bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
)))
3084 clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3085 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
3086 g_hash_table_insert (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
), bb
);
3088 if (bb
->in_scount
== 0) {
3091 sprintf (name
, "finally_ind_bb%d", bb
->block_num
);
3092 val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), name
);
3093 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
3095 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
3097 /* Create a variable to hold the exception var */
3099 ctx
->ex_var
= LLVMBuildAlloca (builder
, ObjRefType (), "exvar");
3103 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3104 * LLVM bblock containing a landing pad causes problems for the
3105 * LLVM optimizer passes.
3107 sprintf (name
, "BB%d_CALL_HANDLER_TARGET", bb
->block_num
);
3108 ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, name
);
3110 ctx
->builder
= old_builder
;
3114 process_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, MonoInst
*ins
)
3116 MonoCompile
*cfg
= ctx
->cfg
;
3117 LLVMValueRef
*values
= ctx
->values
;
3118 LLVMValueRef
*addresses
= ctx
->addresses
;
3119 MonoCallInst
*call
= (MonoCallInst
*)ins
;
3120 MonoMethodSignature
*sig
= call
->signature
;
3121 LLVMValueRef callee
= NULL
, lcall
;
3123 LLVMCallInfo
*cinfo
;
3127 LLVMTypeRef llvm_sig
;
3129 gboolean is_virtual
, calli
, preserveall
;
3130 LLVMBuilderRef builder
= *builder_ref
;
3132 if ((call
->signature
->call_convention
!= MONO_CALL_DEFAULT
) && !((call
->signature
->call_convention
== MONO_CALL_C
) && ctx
->llvm_only
)) {
3133 set_failure (ctx
, "non-default callconv");
3137 cinfo
= call
->cinfo
;
3139 if (call
->rgctx_arg_reg
)
3140 cinfo
->rgctx_arg
= TRUE
;
3141 if (call
->imt_arg_reg
)
3142 cinfo
->imt_arg
= TRUE
;
3144 vretaddr
= (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
|| cinfo
->ret
.storage
== LLVMArgVtypeByRef
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixed
|| cinfo
->ret
.storage
== LLVMArgGsharedvtVariable
|| cinfo
->ret
.storage
== LLVMArgGsharedvtFixedVtype
);
3146 llvm_sig
= sig_to_llvm_sig_full (ctx
, sig
, cinfo
);
3150 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
);
3151 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
);
3153 preserveall
= FALSE
;
3155 /* FIXME: Avoid creating duplicate methods */
3157 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3161 if (cfg
->compile_aot
) {
3162 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
3164 set_failure (ctx
, "can't encode patch");
3167 if (cfg
->llvm_only
&& call
->method
->klass
->image
->assembly
== ctx
->module
->assembly
) {
3169 * Collect instructions representing the callee into a hash so they can be replaced
3170 * by the llvm method for the callee if the callee turns out to be direct
3171 * callable. Currently this only requires it to not fail llvm compilation.
3173 GSList
*l
= (GSList
*)g_hash_table_lookup (ctx
->method_to_callers
, call
->method
);
3174 l
= g_slist_prepend (l
, callee
);
3175 g_hash_table_insert (ctx
->method_to_callers
, call
->method
, l
);
3179 static int tramp_index
;
3182 name
= g_strdup_printf ("tramp_%d", tramp_index
);
3185 #if LLVM_API_VERSION > 100
3187 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3188 * Make all calls through a global. The address of the global will be saved in
3189 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3192 LLVMValueRef tramp_var
= g_hash_table_lookup (ctx
->jit_callees
, call
->method
);
3195 mono_create_jit_trampoline (mono_domain_get (),
3196 call
->method
, &error
);
3197 if (!is_ok (&error
)) {
3198 set_failure (ctx
, mono_error_get_message (&error
));
3199 mono_error_cleanup (&error
);
3203 tramp_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (llvm_sig
, 0), name
);
3204 LLVMSetInitializer (tramp_var
, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64
)(size_t)target
, FALSE
), LLVMPointerType (llvm_sig
, 0)));
3205 LLVMSetLinkage (tramp_var
, LLVMExternalLinkage
);
3206 g_hash_table_insert (ctx
->jit_callees
, call
->method
, tramp_var
);
3208 callee
= LLVMBuildLoad (builder
, tramp_var
, "");
3211 mono_create_jit_trampoline (mono_domain_get (),
3212 call
->method
, &error
);
3213 if (!is_ok (&error
)) {
3215 set_failure (ctx
, mono_error_get_message (&error
));
3216 mono_error_cleanup (&error
);
3220 callee
= LLVMAddFunction (ctx
->lmodule
, name
, llvm_sig
);
3223 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3228 if (!cfg
->llvm_only
&& call
->method
&& strstr (call
->method
->klass
->name
, "AsyncVoidMethodBuilder")) {
3229 /* LLVM miscompiles async methods */
3230 set_failure (ctx
, "#13734");
3235 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
3241 memset (&ji, 0, sizeof (ji));
3242 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3243 ji.data.target = info->name;
3245 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3247 if (cfg
->compile_aot
) {
3248 callee
= get_callee (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
3250 set_failure (ctx
, "can't encode patch");
3254 target
= (gpointer
)mono_icall_get_wrapper (info
);
3255 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3258 if (cfg
->compile_aot
) {
3260 if (cfg
->abs_patches
) {
3261 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3263 callee
= get_callee (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
3265 set_failure (ctx
, "can't encode patch");
3271 set_failure (ctx
, "aot");
3275 #if LLVM_API_VERSION > 100
3276 if (cfg
->abs_patches
) {
3277 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3281 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3282 mono_error_assert_ok (&error
);
3283 callee
= emit_jit_callee (ctx
, "", llvm_sig
, target
);
3285 g_assert_not_reached ();
3288 g_assert_not_reached ();
3291 callee
= LLVMAddFunction (ctx
->lmodule
, "", llvm_sig
);
3293 if (cfg
->abs_patches
) {
3294 MonoJumpInfo
*abs_ji
= (MonoJumpInfo
*)g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
3299 * FIXME: Some trampolines might have
3300 * their own calling convention on some platforms.
3302 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
, &error
);
3303 mono_error_assert_ok (&error
);
3304 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, target
);
3308 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, (gpointer
)call
->fptr
);
3315 int size
= sizeof (gpointer
);
3318 g_assert (ins
->inst_offset
% size
== 0);
3319 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
3321 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
3323 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
3325 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
3330 * Collect and convert arguments
3332 nargs
= (sig
->param_count
* 16) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
+ call
->imt_arg_reg
;
3333 len
= sizeof (LLVMValueRef
) * nargs
;
3334 args
= (LLVMValueRef
*)alloca (len
);
3335 memset (args
, 0, len
);
3336 l
= call
->out_ireg_args
;
3338 if (call
->rgctx_arg_reg
) {
3339 g_assert (values
[call
->rgctx_arg_reg
]);
3340 g_assert (cinfo
->rgctx_arg_pindex
< nargs
);
3342 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3343 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3344 * it using a volatile load.
3347 if (!ctx
->imt_rgctx_loc
)
3348 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3349 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3350 args
[cinfo
->rgctx_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3352 args
[cinfo
->rgctx_arg_pindex
] = convert (ctx
, values
[call
->rgctx_arg_reg
], ctx
->module
->ptr_type
);
3355 if (call
->imt_arg_reg
) {
3356 g_assert (!ctx
->llvm_only
);
3357 g_assert (values
[call
->imt_arg_reg
]);
3358 g_assert (cinfo
->imt_arg_pindex
< nargs
);
3360 if (!ctx
->imt_rgctx_loc
)
3361 ctx
->imt_rgctx_loc
= build_alloca_llvm_type (ctx
, ctx
->module
->ptr_type
, sizeof (gpointer
));
3362 LLVMBuildStore (builder
, convert (ctx
, ctx
->values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
), ctx
->imt_rgctx_loc
);
3363 args
[cinfo
->imt_arg_pindex
] = mono_llvm_build_load (builder
, ctx
->imt_rgctx_loc
, "", TRUE
);
3365 args
[cinfo
->imt_arg_pindex
] = convert (ctx
, values
[call
->imt_arg_reg
], ctx
->module
->ptr_type
);
3368 switch (cinfo
->ret
.storage
) {
3369 case LLVMArgGsharedvtVariable
: {
3370 MonoInst
*var
= get_vreg_to_inst (cfg
, call
->inst
.dreg
);
3372 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
3373 args
[cinfo
->vret_arg_pindex
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), IntPtrType ());
3375 g_assert (addresses
[call
->inst
.dreg
]);
3376 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3382 if (!addresses
[call
->inst
.dreg
])
3383 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3384 g_assert (cinfo
->vret_arg_pindex
< nargs
);
3385 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3386 args
[cinfo
->vret_arg_pindex
] = addresses
[call
->inst
.dreg
];
3388 args
[cinfo
->vret_arg_pindex
] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
3394 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3395 * use the real callee for argument type conversion.
3397 LLVMTypeRef callee_type
= LLVMGetElementType (LLVMTypeOf (callee
));
3398 LLVMTypeRef
*param_types
= (LLVMTypeRef
*)g_alloca (sizeof (LLVMTypeRef
) * LLVMCountParamTypes (callee_type
));
3399 LLVMGetParamTypes (callee_type
, param_types
);
3401 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
3404 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
];
3406 pindex
= ainfo
->pindex
;
3408 regpair
= (guint32
)(gssize
)(l
->data
);
3409 reg
= regpair
& 0xffffff;
3410 args
[pindex
] = values
[reg
];
3411 switch (ainfo
->storage
) {
3412 case LLVMArgVtypeInReg
:
3413 case LLVMArgAsFpArgs
: {
3417 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
)
3418 args
[pindex
+ j
] = LLVMConstNull (LLVMDoubleType ());
3419 pindex
+= ainfo
->ndummy_fpargs
;
3421 g_assert (addresses
[reg
]);
3422 emit_vtype_to_args (ctx
, builder
, ainfo
->type
, addresses
[reg
], ainfo
, args
+ pindex
, &nargs
);
3426 // FIXME: Get rid of the VMOVE
3429 case LLVMArgVtypeByVal
:
3430 g_assert (addresses
[reg
]);
3431 args
[pindex
] = addresses
[reg
];
3433 case LLVMArgVtypeByRef
: {
3434 g_assert (addresses
[reg
]);
3435 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3438 case LLVMArgAsIArgs
:
3439 g_assert (addresses
[reg
]);
3440 args
[pindex
] = LLVMBuildLoad (ctx
->builder
, convert (ctx
, addresses
[reg
], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo
->nslots
), 0)), "");
3442 case LLVMArgVtypeAsScalar
:
3443 g_assert_not_reached ();
3445 case LLVMArgGsharedvtFixed
:
3446 case LLVMArgGsharedvtFixedVtype
:
3447 g_assert (addresses
[reg
]);
3448 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (type_to_llvm_arg_type (ctx
, ainfo
->type
), 0));
3450 case LLVMArgGsharedvtVariable
:
3451 g_assert (addresses
[reg
]);
3452 args
[pindex
] = convert (ctx
, addresses
[reg
], LLVMPointerType (IntPtrType (), 0));
3455 g_assert (args
[pindex
]);
3456 if (i
== 0 && sig
->hasthis
)
3457 args
[pindex
] = convert (ctx
, args
[pindex
], param_types
[pindex
]);
3459 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, ainfo
->type
));
3462 g_assert (pindex
<= nargs
);
3467 // FIXME: Align call sites
3473 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, LLVMCountParamTypes (llvm_sig
));
3476 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3478 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3479 g_assert (MONO_ARCH_IMT_REG
== MONO_ARCH_RGCTX_REG
);
3481 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3482 g_assert (!(call
->rgctx_arg_reg
&& call
->imt_arg_reg
));
3483 if (!sig
->pinvoke
&& !cfg
->llvm_only
)
3484 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
3486 mono_llvm_set_call_preserveall_cc (lcall
);
3488 if (cinfo
->ret
.storage
== LLVMArgVtypeByRef
)
3489 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->vret_arg_pindex
, LLVMStructRetAttribute
);
3490 if (!ctx
->llvm_only
&& call
->rgctx_arg_reg
)
3491 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->rgctx_arg_pindex
, LLVMInRegAttribute
);
3492 if (call
->imt_arg_reg
)
3493 LLVMAddInstrAttribute (lcall
, 1 + cinfo
->imt_arg_pindex
, LLVMInRegAttribute
);
3495 /* Add byval attributes if needed */
3496 for (i
= 0; i
< sig
->param_count
; ++i
) {
3497 LLVMArgInfo
*ainfo
= &call
->cinfo
->args
[i
+ sig
->hasthis
];
3499 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
)
3500 LLVMAddInstrAttribute (lcall
, 1 + ainfo
->pindex
, LLVMByValAttribute
);
3504 * Convert the result
3506 switch (cinfo
->ret
.storage
) {
3507 case LLVMArgVtypeInReg
: {
3508 LLVMValueRef regs
[2];
3510 if (LLVMTypeOf (lcall
) == LLVMVoidType ())
3514 if (!addresses
[ins
->dreg
])
3515 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
3517 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
3518 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
3519 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
3520 emit_args_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
3523 case LLVMArgVtypeByVal
:
3524 if (!addresses
[call
->inst
.dreg
])
3525 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3526 LLVMBuildStore (builder
, lcall
, addresses
[call
->inst
.dreg
]);
3528 case LLVMArgAsIArgs
:
3529 case LLVMArgFpStruct
:
3530 if (!addresses
[call
->inst
.dreg
])
3531 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3532 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3534 case LLVMArgVtypeAsScalar
:
3535 if (!addresses
[call
->inst
.dreg
])
3536 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
3537 LLVMBuildStore (builder
, lcall
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (LLVMTypeOf (lcall
), 0), FALSE
));
3539 case LLVMArgVtypeRetAddr
:
3540 case LLVMArgVtypeByRef
:
3541 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
))) {
3542 /* Some opcodes like STOREX_MEMBASE access these by value */
3543 g_assert (addresses
[call
->inst
.dreg
]);
3544 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3547 case LLVMArgGsharedvtVariable
:
3549 case LLVMArgGsharedvtFixed
:
3550 case LLVMArgGsharedvtFixedVtype
:
3551 values
[ins
->dreg
] = LLVMBuildLoad (builder
, convert_full (ctx
, addresses
[call
->inst
.dreg
], LLVMPointerType (type_to_llvm_type (ctx
, sig
->ret
), 0), FALSE
), "");
3554 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
3555 /* If the method returns an unsigned value, need to zext it */
3556 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
));
3560 *builder_ref
= ctx
->builder
;
3564 emit_llvmonly_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3566 const char *icall_name
= rethrow
? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3567 LLVMValueRef callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3569 LLVMTypeRef exc_type
= type_to_llvm_type (ctx
, &mono_get_exception_class ()->byval_arg
);
3572 LLVMTypeRef fun_sig
= LLVMFunctionType1 (LLVMVoidType (), exc_type
, FALSE
);
3574 if (ctx
->cfg
->compile_aot
) {
3575 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_JIT_ICALL_ADDR
, icall_name
);
3577 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3578 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3579 mono_memory_barrier ();
3582 ctx
->module
->rethrow
= callee
;
3584 ctx
->module
->throw_icall
= callee
;
3588 LLVMValueRef args
[2];
3590 args
[0] = convert (ctx
, exc
, exc_type
);
3591 emit_call (ctx
, bb
, &ctx
->builder
, callee
, args
, 1);
3593 LLVMBuildUnreachable (ctx
->builder
);
3595 ctx
->builder
= create_builder (ctx
);
3599 emit_throw (EmitContext
*ctx
, MonoBasicBlock
*bb
, gboolean rethrow
, LLVMValueRef exc
)
3601 MonoMethodSignature
*throw_sig
;
3602 LLVMValueRef callee
, arg
;
3603 const char *icall_name
;
3605 callee
= rethrow
? ctx
->module
->rethrow
: ctx
->module
->throw_icall
;
3606 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3609 throw_sig
= mono_metadata_signature_alloc (mono_get_corlib (), 1);
3610 throw_sig
->ret
= &mono_get_void_class ()->byval_arg
;
3611 throw_sig
->params
[0] = &mono_get_object_class ()->byval_arg
;
3612 if (ctx
->cfg
->compile_aot
) {
3613 callee
= get_callee (ctx
, sig_to_llvm_sig (ctx
, throw_sig
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3618 * LLVM doesn't push the exception argument, so we need a different
3621 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3623 target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3625 callee
= emit_jit_callee (ctx
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
), target
);
3628 mono_memory_barrier ();
3629 #if LLVM_API_VERSION < 100
3631 ctx
->module
->rethrow
= callee
;
3633 ctx
->module
->throw_icall
= callee
;
3636 arg
= convert (ctx
, exc
, type_to_llvm_type (ctx
, &mono_get_object_class ()->byval_arg
));
3637 emit_call (ctx
, bb
, &ctx
->builder
, callee
, &arg
, 1);
3641 emit_resume_eh (EmitContext
*ctx
, MonoBasicBlock
*bb
)
3643 const char *icall_name
= "mono_llvm_resume_exception";
3644 LLVMValueRef callee
= ctx
->module
->resume_eh
;
3646 LLVMTypeRef fun_sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
3649 if (ctx
->cfg
->compile_aot
) {
3650 callee
= get_callee (ctx
, fun_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3652 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, fun_sig
);
3653 LLVMAddGlobalMapping (ctx
->module
->ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3654 mono_memory_barrier ();
3656 ctx
->module
->resume_eh
= callee
;
3660 emit_call (ctx
, bb
, &ctx
->builder
, callee
, NULL
, 0);
3662 LLVMBuildUnreachable (ctx
->builder
);
3664 ctx
->builder
= create_builder (ctx
);
3668 mono_llvm_emit_clear_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3670 const char *icall_name
= "mono_llvm_clear_exception";
3672 LLVMTypeRef call_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
3673 LLVMValueRef callee
= NULL
;
3676 if (ctx
->cfg
->compile_aot
) {
3677 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3679 // FIXME: This is broken.
3680 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3684 g_assert (builder
&& callee
);
3686 return LLVMBuildCall (builder
, callee
, NULL
, 0, "");
3690 mono_llvm_emit_load_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
)
3692 const char *icall_name
= "mono_llvm_load_exception";
3694 LLVMTypeRef call_sig
= LLVMFunctionType (ObjRefType (), NULL
, 0, FALSE
);
3695 LLVMValueRef callee
= NULL
;
3698 if (ctx
->cfg
->compile_aot
) {
3699 callee
= get_callee (ctx
, call_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3701 // FIXME: This is broken.
3702 callee
= LLVMAddFunction (ctx
->lmodule
, icall_name
, call_sig
);
3706 g_assert (builder
&& callee
);
3708 return LLVMBuildCall (builder
, callee
, NULL
, 0, icall_name
);
3713 mono_llvm_emit_match_exception_call (EmitContext
*ctx
, LLVMBuilderRef builder
, gint32 region_start
, gint32 region_end
)
3715 const char *icall_name
= "mono_llvm_match_exception";
3717 ctx
->builder
= builder
;
3719 const int num_args
= 5;
3720 LLVMValueRef args
[num_args
];
3721 args
[0] = convert (ctx
, get_aotconst (ctx
, MONO_PATCH_INFO_AOT_JIT_INFO
, GINT_TO_POINTER (ctx
->cfg
->method_index
)), IntPtrType ());
3722 args
[1] = LLVMConstInt (LLVMInt32Type (), region_start
, 0);
3723 args
[2] = LLVMConstInt (LLVMInt32Type (), region_end
, 0);
3724 if (ctx
->cfg
->rgctx_var
) {
3725 LLVMValueRef rgctx_alloc
= ctx
->addresses
[ctx
->cfg
->rgctx_var
->dreg
];
3726 g_assert (rgctx_alloc
);
3727 args
[3] = LLVMBuildLoad (builder
, convert (ctx
, rgctx_alloc
, LLVMPointerType (IntPtrType (), 0)), "");
3729 args
[3] = LLVMConstInt (IntPtrType (), 0, 0);
3732 args
[4] = convert (ctx
, ctx
->this_arg
, IntPtrType ());
3734 args
[4] = LLVMConstInt (IntPtrType (), 0, 0);
3736 LLVMTypeRef match_sig
= LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE
);
3737 LLVMValueRef callee
= ctx
->module
->match_exc
;
3740 if (ctx
->cfg
->compile_aot
) {
3741 ctx
->builder
= builder
;
3742 // get_callee expects ctx->builder to be the emitting builder
3743 callee
= get_callee (ctx
, match_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3745 callee
= ctx
->module
->match_exc
= LLVMAddFunction (ctx
->lmodule
, icall_name
, match_sig
);
3746 LLVMAddGlobalMapping (ctx
->module
->ee
, ctx
->module
->match_exc
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3747 ctx
->module
->match_exc
= callee
;
3748 mono_memory_barrier ();
3752 g_assert (builder
&& callee
);
3754 g_assert (ctx
->ex_var
);
3756 return LLVMBuildCall (builder
, callee
, args
, num_args
, icall_name
);
3759 // FIXME: This won't work because the code-finding makes this
3761 /*#define MONO_PERSONALITY_DEBUG*/
3763 #ifdef MONO_PERSONALITY_DEBUG
3764 static const gboolean use_debug_personality
= TRUE
;
3765 static const char *default_personality_name
= "mono_debug_personality";
3767 static const gboolean use_debug_personality
= FALSE
;
3768 static const char *default_personality_name
= "__gxx_personality_v0";
3772 default_cpp_lpad_exc_signature (void)
3774 static gboolean inited
= FALSE
;
3775 static LLVMTypeRef sig
;
3778 LLVMTypeRef signature
[2];
3779 signature
[0] = LLVMPointerType (LLVMInt8Type (), 0);
3780 signature
[1] = LLVMInt32Type ();
3781 sig
= LLVMStructType (signature
, 2, FALSE
);
3789 get_mono_personality (EmitContext
*ctx
)
3791 LLVMValueRef personality
= NULL
;
3792 static gint32 mapping_inited
= FALSE
;
3793 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
3795 if (!use_debug_personality
) {
3796 if (ctx
->cfg
->compile_aot
) {
3797 personality
= get_intrinsic (ctx
, default_personality_name
);
3798 } else if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0) {
3799 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3800 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, personality
);
3803 if (ctx
->cfg
->compile_aot
) {
3804 personality
= get_callee (ctx
, personality_type
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
);
3806 personality
= LLVMAddFunction (ctx
->lmodule
, default_personality_name
, personality_type
);
3807 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, default_personality_name
));
3808 mono_memory_barrier ();
3812 g_assert (personality
);
3816 static LLVMBasicBlockRef
3817 emit_landing_pad (EmitContext
*ctx
, int group_index
, int group_size
)
3819 MonoCompile
*cfg
= ctx
->cfg
;
3820 LLVMBuilderRef old_builder
= ctx
->builder
;
3821 MonoExceptionClause
*group_start
= cfg
->header
->clauses
+ group_index
;
3823 LLVMBuilderRef lpadBuilder
= create_builder (ctx
);
3824 ctx
->builder
= lpadBuilder
;
3826 MonoBasicBlock
*handler_bb
= cfg
->cil_offset_to_bb
[CLAUSE_START (group_start
)];
3827 g_assert (handler_bb
);
3829 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3830 LLVMValueRef personality
= get_mono_personality (ctx
);
3831 g_assert (personality
);
3833 char *bb_name
= g_strdup_printf ("LPAD%d_BB", group_index
);
3834 LLVMBasicBlockRef lpad_bb
= gen_bb (ctx
, bb_name
);
3836 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3837 LLVMValueRef landing_pad
= LLVMBuildLandingPad (lpadBuilder
, default_cpp_lpad_exc_signature (), personality
, 0, "");
3838 g_assert (landing_pad
);
3840 LLVMValueRef cast
= LLVMBuildBitCast (lpadBuilder
, ctx
->module
->sentinel_exception
, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3841 LLVMAddClause (landing_pad
, cast
);
3843 LLVMBasicBlockRef resume_bb
= gen_bb (ctx
, "RESUME_BB");
3844 LLVMBuilderRef resume_builder
= create_builder (ctx
);
3845 ctx
->builder
= resume_builder
;
3846 LLVMPositionBuilderAtEnd (resume_builder
, resume_bb
);
3848 emit_resume_eh (ctx
, handler_bb
);
3851 ctx
->builder
= lpadBuilder
;
3852 LLVMPositionBuilderAtEnd (lpadBuilder
, lpad_bb
);
3854 gboolean finally_only
= TRUE
;
3856 MonoExceptionClause
*group_cursor
= group_start
;
3858 for (int i
= 0; i
< group_size
; i
++) {
3859 if (!(group_cursor
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
))
3860 finally_only
= FALSE
;
3866 // Handle landing pad inlining
3868 if (!finally_only
) {
3869 // So at each level of the exception stack we will match the exception again.
3870 // During that match, we need to compare against the handler types for the current
3871 // protected region. We send the try start and end so that we can only check against
3872 // handlers for this lexical protected region.
3873 LLVMValueRef match
= mono_llvm_emit_match_exception_call (ctx
, lpadBuilder
, group_start
->try_offset
, group_start
->try_offset
+ group_start
->try_len
);
3875 // if returns -1, resume
3876 LLVMValueRef switch_ins
= LLVMBuildSwitch (lpadBuilder
, match
, resume_bb
, group_size
);
3878 // else move to that target bb
3879 for (int i
=0; i
< group_size
; i
++) {
3880 MonoExceptionClause
*clause
= group_start
+ i
;
3881 int clause_index
= clause
- cfg
->header
->clauses
;
3882 MonoBasicBlock
*handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3883 g_assert (handler_bb
);
3884 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3885 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
3888 int clause_index
= group_start
- cfg
->header
->clauses
;
3889 MonoBasicBlock
*finally_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (clause_index
));
3890 g_assert (finally_bb
);
3892 LLVMBuildBr (ctx
->builder
, ctx
->bblocks
[finally_bb
->block_num
].call_handler_target_bb
);
3895 ctx
->builder
= old_builder
;
3902 emit_llvmonly_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBasicBlockRef cbb
)
3904 int clause_index
= MONO_REGION_CLAUSE_INDEX (bb
->region
);
3905 MonoExceptionClause
*clause
= &ctx
->cfg
->header
->clauses
[clause_index
];
3907 // Make exception available to catch blocks
3908 if (!(clause
->flags
& MONO_EXCEPTION_CLAUSE_FINALLY
)) {
3909 LLVMValueRef mono_exc
= mono_llvm_emit_load_exception_call (ctx
, ctx
->builder
);
3911 g_assert (ctx
->ex_var
);
3912 LLVMBuildStore (ctx
->builder
, LLVMBuildBitCast (ctx
->builder
, mono_exc
, ObjRefType (), ""), ctx
->ex_var
);
3914 if (bb
->in_scount
== 1) {
3915 MonoInst
*exvar
= bb
->in_stack
[0];
3916 g_assert (!ctx
->values
[exvar
->dreg
]);
3917 g_assert (ctx
->ex_var
);
3918 ctx
->values
[exvar
->dreg
] = LLVMBuildLoad (ctx
->builder
, ctx
->ex_var
, "save_exception");
3919 emit_volatile_store (ctx
, exvar
->dreg
);
3922 mono_llvm_emit_clear_exception_call (ctx
, ctx
->builder
);
3925 LLVMBuilderRef handler_builder
= create_builder (ctx
);
3926 LLVMBasicBlockRef target_bb
= ctx
->bblocks
[bb
->block_num
].call_handler_target_bb
;
3927 LLVMPositionBuilderAtEnd (handler_builder
, target_bb
);
3929 // Make the handler code end with a jump to cbb
3930 LLVMBuildBr (handler_builder
, cbb
);
3934 emit_handler_start (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef builder
)
3936 MonoCompile
*cfg
= ctx
->cfg
;
3937 LLVMValueRef
*values
= ctx
->values
;
3938 LLVMModuleRef lmodule
= ctx
->lmodule
;
3939 BBInfo
*bblocks
= ctx
->bblocks
;
3941 LLVMValueRef personality
;
3942 LLVMValueRef landing_pad
;
3943 LLVMBasicBlockRef target_bb
;
3945 static int ti_generator
;
3947 LLVMValueRef type_info
;
3951 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3953 if (cfg
->compile_aot
) {
3954 /* Use a dummy personality function */
3955 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
3956 g_assert (personality
);
3958 #if LLVM_API_VERSION > 100
3959 personality
= ctx
->module
->personality
;
3961 LLVMTypeRef personality_type
= LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
);
3962 personality
= LLVMAddFunction (ctx
->lmodule
, "mono_personality", personality_type
);
3963 LLVMAddFunctionAttr (personality
, LLVMNoUnwindAttribute
);
3964 LLVMBasicBlockRef entry_bb
= LLVMAppendBasicBlock (personality
, "ENTRY");
3965 LLVMBuilderRef builder2
= LLVMCreateBuilder ();
3966 LLVMPositionBuilderAtEnd (builder2
, entry_bb
);
3967 LLVMBuildRet (builder2
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
));
3968 ctx
->module
->personality
= personality
;
3969 LLVMDisposeBuilder (builder2
);
3972 static gint32 mapping_inited
;
3974 personality
= LLVMGetNamedFunction (lmodule
, "mono_personality");
3976 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
3977 LLVMAddGlobalMapping (ctx
->module
->ee
, personality
, (gpointer
)mono_personality
);
3981 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
3983 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
3986 * Create the type info
3988 sprintf (ti_name
, "type_info_%d", ti_generator
);
3991 if (cfg
->compile_aot
) {
3992 /* decode_eh_frame () in aot-runtime.c will decode this */
3993 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
3994 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
3997 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3999 LLVMSetLinkage (type_info
, LLVMInternalLinkage
);
4001 #if LLVM_API_VERSION > 100
4002 type_info
= LLVMAddGlobal (lmodule
, LLVMInt32Type (), ti_name
);
4003 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
4008 * After the cfg mempool is freed, the type info will point to stale memory,
4009 * but this is not a problem, since we decode it once in exception_cb during
4012 ti
= (gint32
*)mono_mempool_alloc (cfg
->mempool
, sizeof (gint32
));
4013 *(gint32
*)ti
= clause_index
;
4015 type_info
= LLVMAddGlobal (lmodule
, i8ptr
, ti_name
);
4017 LLVMAddGlobalMapping (ctx
->module
->ee
, type_info
, ti
);
4022 LLVMTypeRef members
[2], ret_type
;
4024 members
[0] = i8ptr
;
4025 members
[1] = LLVMInt32Type ();
4026 ret_type
= LLVMStructType (members
, 2, FALSE
);
4028 landing_pad
= LLVMBuildLandingPad (builder
, ret_type
, personality
, 1, "");
4029 LLVMAddClause (landing_pad
, type_info
);
4031 /* Store the exception into the exvar */
4033 LLVMBuildStore (builder
, convert (ctx
, LLVMBuildExtractValue (builder
, landing_pad
, 0, "ex_obj"), ObjRefType ()), ctx
->ex_var
);
4037 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4038 * code expects control to be transferred to this landing pad even in the
4039 * presence of nested clauses. The landing pad needs to branch to the landing
4040 * pads belonging to nested clauses based on the selector value returned by
4041 * the landing pad instruction, which is passed to the landing pad in a
4042 * register by the EH code.
4044 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4045 g_assert (target_bb
);
4048 * Branch to the correct landing pad
4050 LLVMValueRef ex_selector
= LLVMBuildExtractValue (builder
, landing_pad
, 1, "ex_selector");
4051 LLVMValueRef switch_ins
= LLVMBuildSwitch (builder
, ex_selector
, target_bb
, 0);
4053 for (l
= ctx
->nested_in
[clause_index
]; l
; l
= l
->next
) {
4054 int nesting_clause_index
= GPOINTER_TO_INT (l
->data
);
4055 MonoBasicBlock
*handler_bb
;
4057 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->clause_to_handler
, GINT_TO_POINTER (nesting_clause_index
));
4058 g_assert (handler_bb
);
4060 g_assert (ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4061 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), nesting_clause_index
, FALSE
), ctx
->bblocks
[handler_bb
->block_num
].call_handler_target_bb
);
4064 /* Start a new bblock which CALL_HANDLER can branch to */
4065 target_bb
= bblocks
[bb
->block_num
].call_handler_target_bb
;
4067 ctx
->builder
= builder
= create_builder (ctx
);
4068 LLVMPositionBuilderAtEnd (ctx
->builder
, target_bb
);
4070 ctx
->bblocks
[bb
->block_num
].end_bblock
= target_bb
;
4072 /* Store the exception into the IL level exvar */
4073 if (bb
->in_scount
== 1) {
4074 g_assert (bb
->in_scount
== 1);
4075 exvar
= bb
->in_stack
[0];
4077 // FIXME: This is shared with filter clauses ?
4078 g_assert (!values
[exvar
->dreg
]);
4080 g_assert (ctx
->ex_var
);
4081 values
[exvar
->dreg
] = LLVMBuildLoad (builder
, ctx
->ex_var
, "");
4082 emit_volatile_store (ctx
, exvar
->dreg
);
4088 process_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
4090 MonoCompile
*cfg
= ctx
->cfg
;
4091 MonoMethodSignature
*sig
= ctx
->sig
;
4092 LLVMValueRef method
= ctx
->lmethod
;
4093 LLVMValueRef
*values
= ctx
->values
;
4094 LLVMValueRef
*addresses
= ctx
->addresses
;
4095 LLVMCallInfo
*linfo
= ctx
->linfo
;
4096 BBInfo
*bblocks
= ctx
->bblocks
;
4098 LLVMBasicBlockRef cbb
;
4099 LLVMBuilderRef builder
, starting_builder
;
4100 gboolean has_terminator
;
4102 LLVMValueRef lhs
, rhs
;
4105 cbb
= get_end_bb (ctx
, bb
);
4107 builder
= create_builder (ctx
);
4108 ctx
->builder
= builder
;
4109 LLVMPositionBuilderAtEnd (builder
, cbb
);
4114 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
4115 if (!ctx
->llvm_only
&& !bblocks
[bb
->block_num
].invoke_target
) {
4116 set_failure (ctx
, "handler without invokes");
4121 emit_llvmonly_handler_start (ctx
, bb
, cbb
);
4123 emit_handler_start (ctx
, bb
, builder
);
4126 builder
= ctx
->builder
;
4129 has_terminator
= FALSE
;
4130 starting_builder
= builder
;
4131 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
4132 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
4134 char dname_buf
[128];
4136 emit_dbg_loc (ctx
, builder
, ins
->cil_code
);
4141 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4142 * Start a new bblock. If the llvm optimization passes merge these, we
4143 * can work around that by doing a volatile load + cond branch from
4144 * localloc-ed memory.
4146 //set_failure (ctx, "basic block too long");
4147 cbb
= gen_bb (ctx
, "CONT_LONG_BB");
4148 LLVMBuildBr (ctx
->builder
, cbb
);
4149 ctx
->builder
= builder
= create_builder (ctx
);
4150 LLVMPositionBuilderAtEnd (builder
, cbb
);
4151 ctx
->bblocks
[bb
->block_num
].end_bblock
= cbb
;
4156 /* There could be instructions after a terminator, skip them */
4159 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
4160 sprintf (dname_buf
, "t%d", ins
->dreg
);
4164 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
4165 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
4167 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) && var
->opcode
!= OP_GSHAREDVT_ARG_REGOFFSET
) {
4168 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
4170 /* It is ok for SETRET to have an uninitialized argument */
4171 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
) {
4172 set_failure (ctx
, "sreg1");
4175 lhs
= values
[ins
->sreg1
];
4181 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
4182 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
4183 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
4184 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
4186 if (!values
[ins
->sreg2
]) {
4187 set_failure (ctx
, "sreg2");
4190 rhs
= values
[ins
->sreg2
];
4196 //mono_print_ins (ins);
4197 switch (ins
->opcode
) {
4200 case OP_LIVERANGE_START
:
4201 case OP_LIVERANGE_END
:
4204 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
4207 #if SIZEOF_VOID_P == 4
4208 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4210 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
4214 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
4218 values
[ins
->dreg
] = LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
);
4220 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
4222 case OP_DUMMY_ICONST
:
4223 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4225 case OP_DUMMY_I8CONST
:
4226 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
4228 case OP_DUMMY_R8CONST
:
4229 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), 0.0f
);
4232 LLVMBasicBlockRef target_bb
= get_bb (ctx
, ins
->inst_target_bb
);
4233 LLVMBuildBr (builder
, target_bb
);
4234 has_terminator
= TRUE
;
4241 LLVMBasicBlockRef new_bb
;
4242 LLVMBuilderRef new_builder
;
4244 // The default branch is already handled
4245 // FIXME: Handle it here
4247 /* Start new bblock */
4248 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
4249 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
4251 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4252 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
4253 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
4254 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
4256 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
4259 new_builder
= create_builder (ctx
);
4260 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
4261 LLVMBuildUnreachable (new_builder
);
4263 has_terminator
= TRUE
;
4264 g_assert (!ins
->next
);
4270 switch (linfo
->ret
.storage
) {
4271 case LLVMArgVtypeInReg
: {
4272 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4273 LLVMValueRef val
, addr
, retval
;
4276 retval
= LLVMGetUndef (ret_type
);
4278 if (!addresses
[ins
->sreg1
]) {
4280 * The return type is an LLVM vector type, have to convert between it and the
4281 * real return type which is a struct type.
4283 g_assert (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->ret
)));
4284 /* Convert to 2xi64 first */
4285 val
= LLVMBuildBitCast (builder
, values
[ins
->sreg1
], LLVMVectorType (IntPtrType (), 2), "");
4287 for (i
= 0; i
< 2; ++i
) {
4288 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4289 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildExtractElement (builder
, val
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), ""), i
, "");
4291 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4295 addr
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), "");
4296 for (i
= 0; i
< 2; ++i
) {
4297 if (linfo
->ret
.pair_storage
[i
] == LLVMArgInIReg
) {
4298 LLVMValueRef indexes
[2], part_addr
;
4300 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
4301 indexes
[1] = LLVMConstInt (LLVMInt32Type (), i
, FALSE
);
4302 part_addr
= LLVMBuildGEP (builder
, addr
, indexes
, 2, "");
4304 retval
= LLVMBuildInsertValue (builder
, retval
, LLVMBuildLoad (builder
, part_addr
, ""), i
, "");
4306 g_assert (linfo
->ret
.pair_storage
[i
] == LLVMArgNone
);
4310 LLVMBuildRet (builder
, retval
);
4313 case LLVMArgVtypeAsScalar
: {
4314 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4315 LLVMValueRef retval
;
4317 g_assert (addresses
[ins
->sreg1
]);
4319 retval
= LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0), ""), "");
4320 LLVMBuildRet (builder
, retval
);
4323 case LLVMArgVtypeByVal
: {
4324 LLVMValueRef retval
;
4326 g_assert (addresses
[ins
->sreg1
]);
4327 retval
= LLVMBuildLoad (builder
, addresses
[ins
->sreg1
], "");
4328 LLVMBuildRet (builder
, retval
);
4331 case LLVMArgVtypeByRef
: {
4332 LLVMBuildRetVoid (builder
);
4335 case LLVMArgGsharedvtFixed
: {
4336 LLVMTypeRef ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
4337 /* The return value is in lhs, need to store to the vret argument */
4338 /* sreg1 might not be set */
4340 g_assert (cfg
->vret_addr
);
4341 g_assert (values
[cfg
->vret_addr
->dreg
]);
4342 LLVMBuildStore (builder
, convert (ctx
, lhs
, ret_type
), convert (ctx
, values
[cfg
->vret_addr
->dreg
], LLVMPointerType (ret_type
, 0)));
4344 LLVMBuildRetVoid (builder
);
4347 case LLVMArgGsharedvtFixedVtype
: {
4349 LLVMBuildRetVoid (builder
);
4352 case LLVMArgGsharedvtVariable
: {
4354 LLVMBuildRetVoid (builder
);
4357 case LLVMArgVtypeRetAddr
: {
4358 LLVMBuildRetVoid (builder
);
4361 case LLVMArgAsIArgs
:
4362 case LLVMArgFpStruct
: {
4363 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
4364 LLVMValueRef retval
;
4366 g_assert (addresses
[ins
->sreg1
]);
4367 retval
= LLVMBuildLoad (builder
, convert (ctx
, addresses
[ins
->sreg1
], LLVMPointerType (ret_type
, 0)), "");
4368 LLVMBuildRet (builder
, retval
);
4372 case LLVMArgNormal
: {
4373 if (!lhs
|| ctx
->is_dead
[ins
->sreg1
]) {
4375 * The method did not set its return value, probably because it
4376 * ends with a throw.
4379 LLVMBuildRetVoid (builder
);
4381 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
4383 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
4385 has_terminator
= TRUE
;
4389 g_assert_not_reached ();
4398 case OP_ICOMPARE_IMM
:
4399 case OP_LCOMPARE_IMM
:
4400 case OP_COMPARE_IMM
: {
4402 LLVMValueRef cmp
, args
[16];
4403 gboolean likely
= (ins
->flags
& MONO_INST_LIKELY
) != 0;
4405 if (ins
->next
->opcode
== OP_NOP
)
4408 if (ins
->next
->opcode
== OP_BR
)
4409 /* The comparison result is not needed */
4412 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
4414 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
4415 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4416 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4418 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4419 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4420 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4422 if (ins
->opcode
== OP_LCOMPARE
) {
4423 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
4424 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
4426 if (ins
->opcode
== OP_ICOMPARE
) {
4427 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4428 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
4432 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4433 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
4434 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
4435 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
4438 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4439 if (ins
->opcode
== OP_FCOMPARE
) {
4440 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4441 } else if (ins
->opcode
== OP_RCOMPARE
) {
4442 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4443 } else if (ins
->opcode
== OP_COMPARE_IMM
) {
4444 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& ins
->inst_imm
== 0)
4445 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, LLVMConstNull (LLVMTypeOf (lhs
)), "");
4447 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
4448 } else if (ins
->opcode
== OP_LCOMPARE_IMM
) {
4449 if (SIZEOF_REGISTER
== 4 && COMPILE_LLVM (cfg
)) {
4450 /* The immediate is encoded in two fields */
4451 guint64 l
= ((guint64
)(guint32
)ins
->inst_offset
<< 32) | ((guint32
)ins
->inst_imm
);
4452 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l
, FALSE
), "");
4454 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins
->inst_imm
, FALSE
), "");
4457 else if (ins
->opcode
== OP_COMPARE
) {
4458 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
&& LLVMTypeOf (lhs
) == LLVMTypeOf (rhs
))
4459 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4461 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
4463 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
4467 args
[1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
4468 cmp
= LLVMBuildCall (ctx
->builder
, get_intrinsic (ctx
, "llvm.expect.i1"), args
, 2, "");
4471 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
4472 if (ins
->next
->inst_true_bb
== ins
->next
->inst_false_bb
) {
4474 * If the target bb contains PHI instructions, LLVM requires
4475 * two PHI entries for this bblock, while we only generate one.
4476 * So convert this to an unconditional bblock. (bxc #171).
4478 LLVMBuildBr (builder
, get_bb (ctx
, ins
->next
->inst_true_bb
));
4480 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
4482 has_terminator
= TRUE
;
4483 } else if (MONO_IS_SETCC (ins
->next
)) {
4484 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
4486 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4488 /* Add stores for volatile variables */
4489 emit_volatile_store (ctx
, ins
->next
->dreg
);
4490 } else if (MONO_IS_COND_EXC (ins
->next
)) {
4491 emit_cond_system_exception (ctx
, bb
, (const char*)ins
->next
->inst_p1
, cmp
);
4494 builder
= ctx
->builder
;
4496 set_failure (ctx
, "next");
4514 rel
= mono_opcode_to_cond (ins
->opcode
);
4516 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
4517 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4528 rel
= mono_opcode_to_cond (ins
->opcode
);
4530 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMFloatType ()), convert (ctx
, rhs
, LLVMFloatType ()), "");
4531 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
4539 gboolean empty
= TRUE
;
4541 /* Check that all input bblocks really branch to us */
4542 for (i
= 0; i
< bb
->in_count
; ++i
) {
4543 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
4544 ins
->inst_phi_args
[i
+ 1] = -1;
4550 /* LLVM doesn't like phi instructions with zero operands */
4551 ctx
->is_dead
[ins
->dreg
] = TRUE
;
4555 /* Created earlier, insert it now */
4556 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
4558 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
4559 int sreg1
= ins
->inst_phi_args
[i
+ 1];
4563 * Count the number of times the incoming bblock branches to us,
4564 * since llvm requires a separate entry for each.
4566 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
4567 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
4570 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
4571 if (switch_ins
->inst_many_bb
[j
] == bb
)
4578 /* Remember for later */
4579 for (j
= 0; j
< count
; ++j
) {
4580 PhiNode
*node
= (PhiNode
*)mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
4583 node
->in_bb
= bb
->in_bb
[i
];
4585 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
);
4595 values
[ins
->dreg
] = lhs
;
4599 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
4602 values
[ins
->dreg
] = lhs
;
4604 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
4606 * This is added by the spilling pass in case of the JIT,
4607 * but we have to do it ourselves.
4609 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
4613 case OP_MOVE_F_TO_I4
: {
4614 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), ""), LLVMInt32Type (), "");
4617 case OP_MOVE_I4_TO_F
: {
4618 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, LLVMBuildBitCast (builder
, lhs
, LLVMFloatType (), ""), LLVMDoubleType (), "");
4621 case OP_MOVE_F_TO_I8
: {
4622 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMInt64Type (), "");
4625 case OP_MOVE_I8_TO_F
: {
4626 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, lhs
, LLVMDoubleType (), "");
4659 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4660 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
4662 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, rhs
);
4665 builder
= ctx
->builder
;
4667 switch (ins
->opcode
) {
4670 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
4674 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
4678 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
4682 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
4686 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
4690 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
4694 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
4698 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4702 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
4706 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
4710 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
4714 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
4718 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
4722 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
4726 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4729 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4732 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4736 g_assert_not_reached ();
4743 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4744 rhs
= convert (ctx
, rhs
, LLVMFloatType ());
4745 switch (ins
->opcode
) {
4747 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
4750 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
4753 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
4756 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
4759 g_assert_not_reached ();
4768 case OP_IREM_UN_IMM
:
4770 case OP_IDIV_UN_IMM
:
4776 case OP_ISHR_UN_IMM
:
4786 case OP_LSHR_UN_IMM
:
4792 case OP_SHR_UN_IMM
: {
4795 if (spec
[MONO_INST_SRC1
] == 'l') {
4796 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
4798 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4801 emit_div_check (ctx
, builder
, bb
, ins
, lhs
, imm
);
4804 builder
= ctx
->builder
;
4806 #if SIZEOF_VOID_P == 4
4807 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
4808 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
4811 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
4812 lhs
= convert (ctx
, lhs
, IntPtrType ());
4813 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
4814 switch (ins
->opcode
) {
4818 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
4822 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
4827 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
4831 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
4833 case OP_IDIV_UN_IMM
:
4834 case OP_LDIV_UN_IMM
:
4835 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
4839 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
4841 case OP_IREM_UN_IMM
:
4842 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
4847 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
4851 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
4855 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
4860 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
4865 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
4867 case OP_ISHR_UN_IMM
:
4868 /* This is used to implement conv.u4, so the lhs could be an i8 */
4869 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
4870 imm
= convert (ctx
, imm
, LLVMInt32Type ());
4871 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4873 case OP_LSHR_UN_IMM
:
4875 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
4878 g_assert_not_reached ();
4883 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4886 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
4889 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
4890 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
4893 lhs
= convert (ctx
, lhs
, LLVMFloatType ());
4894 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMFloatType (), 0.0), lhs
, dname
);
4897 guint32 v
= 0xffffffff;
4898 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
4902 guint64 v
= 0xffffffffffffffffLL
;
4903 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
4906 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4908 LLVMValueRef v1
, v2
;
4910 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
4911 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
4912 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
4917 case OP_ICONV_TO_I1
:
4918 case OP_ICONV_TO_I2
:
4919 case OP_ICONV_TO_I4
:
4920 case OP_ICONV_TO_U1
:
4921 case OP_ICONV_TO_U2
:
4922 case OP_ICONV_TO_U4
:
4923 case OP_LCONV_TO_I1
:
4924 case OP_LCONV_TO_I2
:
4925 case OP_LCONV_TO_U1
:
4926 case OP_LCONV_TO_U2
:
4927 case OP_LCONV_TO_U4
: {
4930 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
);
4932 /* Have to do two casts since our vregs have type int */
4933 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
4935 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
4937 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
4940 case OP_ICONV_TO_I8
:
4941 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
4943 case OP_ICONV_TO_U8
:
4944 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
4946 case OP_FCONV_TO_I4
:
4947 case OP_RCONV_TO_I4
:
4948 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
4950 case OP_FCONV_TO_I1
:
4951 case OP_RCONV_TO_I1
:
4952 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
4954 case OP_FCONV_TO_U1
:
4955 case OP_RCONV_TO_U1
:
4956 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildTrunc (builder
, LLVMBuildFPToUI (builder
, lhs
, IntPtrType (), dname
), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4958 case OP_FCONV_TO_I2
:
4959 case OP_RCONV_TO_I2
:
4960 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
4962 case OP_FCONV_TO_U2
:
4963 case OP_RCONV_TO_U2
:
4964 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
4966 case OP_RCONV_TO_U4
:
4967 values
[ins
->dreg
] = LLVMBuildFPToUI (builder
, lhs
, LLVMInt32Type (), dname
);
4969 case OP_FCONV_TO_I8
:
4970 case OP_RCONV_TO_I8
:
4971 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
4974 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
4976 case OP_ICONV_TO_R8
:
4977 case OP_LCONV_TO_R8
:
4978 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
4980 case OP_ICONV_TO_R_UN
:
4981 case OP_LCONV_TO_R_UN
:
4982 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
4984 #if SIZEOF_VOID_P == 4
4987 case OP_LCONV_TO_I4
:
4988 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
4990 case OP_ICONV_TO_R4
:
4991 case OP_LCONV_TO_R4
:
4992 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
4994 values
[ins
->dreg
] = v
;
4996 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
4998 case OP_FCONV_TO_R4
:
4999 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
5001 values
[ins
->dreg
] = v
;
5003 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
5005 case OP_RCONV_TO_R8
:
5006 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, lhs
, LLVMDoubleType (), dname
);
5008 case OP_RCONV_TO_R4
:
5009 values
[ins
->dreg
] = lhs
;
5012 values
[ins
->dreg
] = LLVMBuildSExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5015 values
[ins
->dreg
] = LLVMBuildZExt (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), LLVMInt64Type (), dname
);
5018 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
5020 case OP_LOCALLOC_IMM
: {
5023 guint32 size
= ins
->inst_imm
;
5024 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
5026 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
5028 if (ins
->flags
& MONO_INST_INIT
) {
5029 LLVMValueRef args
[5];
5032 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5033 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
5034 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5035 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5036 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5039 values
[ins
->dreg
] = v
;
5043 LLVMValueRef v
, size
;
5045 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
), "");
5047 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
5049 if (ins
->flags
& MONO_INST_INIT
) {
5050 LLVMValueRef args
[5];
5053 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5055 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
5056 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5057 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5059 values
[ins
->dreg
] = v
;
5063 case OP_LOADI1_MEMBASE
:
5064 case OP_LOADU1_MEMBASE
:
5065 case OP_LOADI2_MEMBASE
:
5066 case OP_LOADU2_MEMBASE
:
5067 case OP_LOADI4_MEMBASE
:
5068 case OP_LOADU4_MEMBASE
:
5069 case OP_LOADI8_MEMBASE
:
5070 case OP_LOADR4_MEMBASE
:
5071 case OP_LOADR8_MEMBASE
:
5072 case OP_LOAD_MEMBASE
:
5080 LLVMValueRef base
, index
, addr
;
5082 gboolean sext
= FALSE
, zext
= FALSE
;
5083 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5085 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5090 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
)) {
5091 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
5097 if (ins
->inst_offset
== 0) {
5099 } else if (ins
->inst_offset
% size
!= 0) {
5100 /* Unaligned load */
5101 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5102 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5104 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5105 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5109 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5111 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, base
, dname
, is_volatile
, LLVM_BARRIER_NONE
);
5113 if (!is_volatile
&& (ins
->flags
& MONO_INST_INVARIANT_LOAD
)) {
5115 * These will signal LLVM that these loads do not alias any stores, and
5116 * they can't fail, allowing them to be hoisted out of loops.
5118 set_invariant_load_flag (values
[ins
->dreg
]);
5119 #if LLVM_API_VERSION < 100
5120 set_metadata_flag (values
[ins
->dreg
], "mono.nofail.load");
5125 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5127 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5128 else if (!cfg
->r4fp
&& ins
->opcode
== OP_LOADR4_MEMBASE
)
5129 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
5133 case OP_STOREI1_MEMBASE_REG
:
5134 case OP_STOREI2_MEMBASE_REG
:
5135 case OP_STOREI4_MEMBASE_REG
:
5136 case OP_STOREI8_MEMBASE_REG
:
5137 case OP_STORER4_MEMBASE_REG
:
5138 case OP_STORER8_MEMBASE_REG
:
5139 case OP_STORE_MEMBASE_REG
: {
5141 LLVMValueRef index
, addr
, base
;
5143 gboolean sext
= FALSE
, zext
= FALSE
;
5144 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5146 if (!values
[ins
->inst_destbasereg
]) {
5147 set_failure (ctx
, "inst_destbasereg");
5151 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5153 base
= values
[ins
->inst_destbasereg
];
5154 if (ins
->inst_offset
% size
!= 0) {
5155 /* Unaligned store */
5156 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5157 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5159 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5160 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5162 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5166 case OP_STOREI1_MEMBASE_IMM
:
5167 case OP_STOREI2_MEMBASE_IMM
:
5168 case OP_STOREI4_MEMBASE_IMM
:
5169 case OP_STOREI8_MEMBASE_IMM
:
5170 case OP_STORE_MEMBASE_IMM
: {
5172 LLVMValueRef index
, addr
, base
;
5174 gboolean sext
= FALSE
, zext
= FALSE
;
5175 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5177 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5179 base
= values
[ins
->inst_destbasereg
];
5180 if (ins
->inst_offset
% size
!= 0) {
5181 /* Unaligned store */
5182 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
5183 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
5185 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5186 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5188 emit_store (ctx
, bb
, &builder
, size
, convert (ctx
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)), base
, is_volatile
);
5193 emit_load_general (ctx
, bb
, &builder
, sizeof (gpointer
), convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), lhs
, "", TRUE
, LLVM_BARRIER_NONE
);
5195 case OP_OUTARG_VTRETADDR
:
5203 case OP_VOIDCALL_MEMBASE
:
5204 case OP_CALL_MEMBASE
:
5205 case OP_LCALL_MEMBASE
:
5206 case OP_FCALL_MEMBASE
:
5207 case OP_RCALL_MEMBASE
:
5208 case OP_VCALL_MEMBASE
:
5209 case OP_VOIDCALL_REG
:
5214 case OP_VCALL_REG
: {
5215 process_call (ctx
, bb
, &builder
, ins
);
5220 LLVMValueRef indexes
[2];
5221 MonoJumpInfo
*tmp_ji
, *ji
;
5222 LLVMValueRef got_entry_addr
;
5226 * FIXME: Can't allocate from the cfg mempool since that is freed if
5227 * the LLVM compile fails.
5229 tmp_ji
= g_new0 (MonoJumpInfo
, 1);
5230 tmp_ji
->type
= (MonoJumpInfoType
)ins
->inst_c1
;
5231 tmp_ji
->data
.target
= ins
->inst_p0
;
5233 ji
= mono_aot_patch_info_dup (tmp_ji
);
5236 if (ji
->type
== MONO_PATCH_INFO_ICALL_ADDR
) {
5237 char *symbol
= mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL
, ji
->data
.target
);
5240 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5241 * resolvable at runtime using dlsym ().
5244 values
[ins
->dreg
] = LLVMConstInt (IntPtrType (), 0, FALSE
);
5249 ji
->next
= cfg
->patch_info
;
5250 cfg
->patch_info
= ji
;
5252 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5253 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
5254 ctx
->module
->max_got_offset
= MAX (ctx
->module
->max_got_offset
, got_offset
);
5255 if (!mono_aot_is_shared_got_offset (got_offset
)) {
5256 //mono_print_ji (ji);
5258 ctx
->has_got_access
= TRUE
;
5261 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5262 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
5263 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->module
->got_var
, indexes
, 2, "");
5265 name
= get_aotconst_name (ji
->type
, ji
->data
.target
, got_offset
);
5266 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, name
);
5268 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5269 if (!cfg
->llvm_only
)
5270 set_invariant_load_flag (values
[ins
->dreg
]);
5273 case OP_NOT_REACHED
:
5274 LLVMBuildUnreachable (builder
);
5275 has_terminator
= TRUE
;
5276 g_assert (bb
->block_num
< cfg
->max_block_num
);
5277 ctx
->unreachable
[bb
->block_num
] = TRUE
;
5278 /* Might have instructions after this */
5280 MonoInst
*next
= ins
->next
;
5282 * FIXME: If later code uses the regs defined by these instructions,
5283 * compilation will fail.
5285 MONO_DELETE_INS (bb
, next
);
5289 MonoInst
*var
= ins
->inst_i0
;
5291 if (var
->opcode
== OP_VTARG_ADDR
) {
5292 /* The variable contains the vtype address */
5293 values
[ins
->dreg
] = values
[var
->dreg
];
5294 } else if (var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5295 values
[ins
->dreg
] = emit_gsharedvt_ldaddr (ctx
, var
->dreg
);
5297 values
[ins
->dreg
] = addresses
[var
->dreg
];
5302 LLVMValueRef args
[1];
5304 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5305 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sin.f64"), args
, 1, dname
);
5309 LLVMValueRef args
[1];
5311 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5312 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.cos.f64"), args
, 1, dname
);
5316 LLVMValueRef args
[1];
5318 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5319 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.sqrt.f64"), args
, 1, dname
);
5323 LLVMValueRef args
[1];
5325 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
5326 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, "fabs"), args
, 1, dname
);
5340 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5341 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
5343 switch (ins
->opcode
) {
5346 v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
5350 v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
5354 v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
5358 v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
5361 g_assert_not_reached ();
5364 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
5367 case OP_ATOMIC_EXCHANGE_I4
:
5368 case OP_ATOMIC_EXCHANGE_I8
: {
5369 LLVMValueRef args
[2];
5372 if (ins
->opcode
== OP_ATOMIC_EXCHANGE_I4
)
5373 t
= LLVMInt32Type ();
5375 t
= LLVMInt64Type ();
5377 g_assert (ins
->inst_offset
== 0);
5379 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5380 args
[1] = convert (ctx
, rhs
, t
);
5382 values
[ins
->dreg
] = mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_XCHG
, args
[0], args
[1]);
5385 case OP_ATOMIC_ADD_I4
:
5386 case OP_ATOMIC_ADD_I8
: {
5387 LLVMValueRef args
[2];
5390 if (ins
->opcode
== OP_ATOMIC_ADD_I4
)
5391 t
= LLVMInt32Type ();
5393 t
= LLVMInt64Type ();
5395 g_assert (ins
->inst_offset
== 0);
5397 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5398 args
[1] = convert (ctx
, rhs
, t
);
5399 values
[ins
->dreg
] = LLVMBuildAdd (builder
, mono_llvm_build_atomic_rmw (builder
, LLVM_ATOMICRMW_OP_ADD
, args
[0], args
[1]), args
[1], dname
);
5402 case OP_ATOMIC_CAS_I4
:
5403 case OP_ATOMIC_CAS_I8
: {
5404 LLVMValueRef args
[3], val
;
5407 if (ins
->opcode
== OP_ATOMIC_CAS_I4
)
5408 t
= LLVMInt32Type ();
5410 t
= LLVMInt64Type ();
5412 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
5414 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
5416 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
5417 val
= mono_llvm_build_cmpxchg (builder
, args
[0], args
[1], args
[2]);
5418 /* cmpxchg returns a pair */
5419 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, "");
5422 case OP_MEMORY_BARRIER
: {
5423 mono_llvm_build_fence (builder
, (BarrierKind
) ins
->backend
.memory_barrier_kind
);
5426 case OP_ATOMIC_LOAD_I1
:
5427 case OP_ATOMIC_LOAD_I2
:
5428 case OP_ATOMIC_LOAD_I4
:
5429 case OP_ATOMIC_LOAD_I8
:
5430 case OP_ATOMIC_LOAD_U1
:
5431 case OP_ATOMIC_LOAD_U2
:
5432 case OP_ATOMIC_LOAD_U4
:
5433 case OP_ATOMIC_LOAD_U8
:
5434 case OP_ATOMIC_LOAD_R4
:
5435 case OP_ATOMIC_LOAD_R8
: {
5436 #if LLVM_API_VERSION > 100
5438 gboolean sext
, zext
;
5440 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5441 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5442 LLVMValueRef index
, addr
;
5444 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5449 if (ins
->inst_offset
!= 0) {
5450 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5451 addr
= LLVMBuildGEP (builder
, convert (ctx
, lhs
, LLVMPointerType (t
, 0)), &index
, 1, "");
5456 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
5458 values
[ins
->dreg
] = emit_load_general (ctx
, bb
, &builder
, size
, addr
, lhs
, dname
, is_volatile
, barrier
);
5461 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5463 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
5466 set_failure (ctx
, "atomic mono.load intrinsic");
5470 case OP_ATOMIC_STORE_I1
:
5471 case OP_ATOMIC_STORE_I2
:
5472 case OP_ATOMIC_STORE_I4
:
5473 case OP_ATOMIC_STORE_I8
:
5474 case OP_ATOMIC_STORE_U1
:
5475 case OP_ATOMIC_STORE_U2
:
5476 case OP_ATOMIC_STORE_U4
:
5477 case OP_ATOMIC_STORE_U8
:
5478 case OP_ATOMIC_STORE_R4
:
5479 case OP_ATOMIC_STORE_R8
: {
5481 gboolean sext
, zext
;
5483 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
5484 BarrierKind barrier
= (BarrierKind
) ins
->backend
.memory_barrier_kind
;
5485 LLVMValueRef index
, addr
, value
, base
;
5487 #if LLVM_API_VERSION < 100
5488 if (!cfg
->llvm_only
) {
5489 set_failure (ctx
, "atomic mono.store intrinsic");
5494 if (!values
[ins
->inst_destbasereg
]) {
5495 set_failure (ctx
, "inst_destbasereg");
5499 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
5501 base
= values
[ins
->inst_destbasereg
];
5502 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
5503 addr
= LLVMBuildGEP (builder
, convert (ctx
, base
, LLVMPointerType (t
, 0)), &index
, 1, "");
5504 value
= convert (ctx
, values
[ins
->sreg1
], t
);
5506 emit_store_general (ctx
, bb
, &builder
, size
, value
, addr
, base
, is_volatile
, barrier
);
5509 case OP_RELAXED_NOP
: {
5510 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5511 emit_call (ctx
, bb
, &builder
, get_intrinsic (ctx
, "llvm.x86.sse2.pause"), NULL
, 0);
5518 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5520 // 257 == FS segment register
5521 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5523 // 256 == GS segment register
5524 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5527 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
5528 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5529 /* See mono_amd64_emit_tls_get () */
5530 int offset
= mono_amd64_get_tls_gs_offset () + (ins
->inst_offset
* 8);
5532 // 256 == GS segment register
5533 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5534 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), offset
, TRUE
), ptrtype
, ""), "");
5536 set_failure (ctx
, "opcode tls-get");
5542 case OP_TLS_GET_REG
: {
5543 #if defined(TARGET_AMD64) && defined(__linux__)
5544 // 257 == FS segment register
5545 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
5546 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt64Type ()), ptrtype
, ""), "");
5547 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5548 /* See emit_tls_get_reg () */
5549 // 256 == GS segment register
5550 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5551 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, convert (ctx
, lhs
, LLVMInt32Type ()), ptrtype
, ""), "");
5553 set_failure (ctx
, "opcode tls-get");
5559 case OP_TLS_SET_REG
: {
5560 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5561 /* See emit_tls_get_reg () */
5562 // 256 == GS segment register
5563 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
5564 LLVMBuildStore (builder
, convert (ctx
, lhs
, IntPtrType ()), LLVMBuildIntToPtr (builder
, convert (ctx
, rhs
, LLVMInt32Type ()), ptrtype
, ""));
5566 set_failure (ctx
, "opcode tls-set-reg");
5571 case OP_GC_SAFE_POINT
: {
5572 LLVMValueRef val
, cmp
, callee
;
5573 LLVMBasicBlockRef poll_bb
, cont_bb
;
5574 static LLVMTypeRef sig
;
5575 const char *icall_name
= "mono_threads_state_poll";
5578 sig
= LLVMFunctionType0 (LLVMVoidType (), FALSE
);
5582 * mono_threads_state_poll ();
5583 * FIXME: Use a preserveall wrapper
5585 val
= mono_llvm_build_load (builder
, convert (ctx
, lhs
, LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
5586 cmp
= LLVMBuildICmp (builder
, LLVMIntEQ
, val
, LLVMConstNull (LLVMTypeOf (val
)), "");
5587 poll_bb
= gen_bb (ctx
, "POLL_BB");
5588 cont_bb
= gen_bb (ctx
, "CONT_BB");
5589 LLVMBuildCondBr (builder
, cmp
, cont_bb
, poll_bb
);
5591 ctx
->builder
= builder
= create_builder (ctx
);
5592 LLVMPositionBuilderAtEnd (builder
, poll_bb
);
5594 if (ctx
->cfg
->compile_aot
) {
5595 callee
= get_callee (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5597 gpointer target
= resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
5598 callee
= emit_jit_callee (ctx
, icall_name
, sig
, target
);
5600 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
5601 LLVMBuildBr (builder
, cont_bb
);
5603 ctx
->builder
= builder
= create_builder (ctx
);
5604 LLVMPositionBuilderAtEnd (builder
, cont_bb
);
5605 ctx
->bblocks
[bb
->block_num
].end_bblock
= cont_bb
;
5613 case OP_IADD_OVF_UN
:
5615 case OP_ISUB_OVF_UN
:
5617 case OP_IMUL_OVF_UN
:
5619 case OP_LADD_OVF_UN
:
5621 case OP_LSUB_OVF_UN
:
5623 case OP_LMUL_OVF_UN
:
5625 LLVMValueRef args
[2], val
, ovf
, func
;
5627 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
5628 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
5629 func
= get_intrinsic (ctx
, ovf_op_to_intrins (ins
->opcode
));
5631 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
5632 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
5633 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
5634 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
5637 builder
= ctx
->builder
;
5643 * We currently model them using arrays. Promotion to local vregs is
5644 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5645 * so we always have an entry in cfg->varinfo for them.
5646 * FIXME: Is this needed ?
5649 MonoClass
*klass
= ins
->klass
;
5650 LLVMValueRef args
[5];
5654 set_failure (ctx
, "!klass");
5658 if (!addresses
[ins
->dreg
])
5659 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5660 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5661 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
5662 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5664 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5665 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5666 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memset.p0i8.i32"), args
, 5, "");
5669 case OP_DUMMY_VZERO
:
5672 case OP_STOREV_MEMBASE
:
5673 case OP_LOADV_MEMBASE
:
5675 MonoClass
*klass
= ins
->klass
;
5676 LLVMValueRef src
= NULL
, dst
, args
[5];
5677 gboolean done
= FALSE
;
5681 set_failure (ctx
, "!klass");
5685 if (mini_is_gsharedvt_klass (klass
)) {
5687 set_failure (ctx
, "gsharedvt");
5691 switch (ins
->opcode
) {
5692 case OP_STOREV_MEMBASE
:
5693 if (cfg
->gen_write_barriers
&& klass
->has_references
&& ins
->inst_destbasereg
!= cfg
->frame_reg
&&
5694 LLVMGetInstructionOpcode (values
[ins
->inst_destbasereg
]) != LLVMAlloca
) {
5695 /* Decomposed earlier */
5696 g_assert_not_reached ();
5699 if (!addresses
[ins
->sreg1
]) {
5701 g_assert (values
[ins
->sreg1
]);
5702 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));
5703 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
5706 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5707 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5710 case OP_LOADV_MEMBASE
:
5711 if (!addresses
[ins
->dreg
])
5712 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5713 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
5714 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5717 if (!addresses
[ins
->sreg1
])
5718 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
5719 if (!addresses
[ins
->dreg
])
5720 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
5721 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
5722 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
5725 g_assert_not_reached ();
5735 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
5736 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5738 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
5739 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
5740 LLVMBuildCall (builder
, get_intrinsic (ctx
, "llvm.memcpy.p0i8.p0i8.i32"), args
, 5, "");
5743 case OP_LLVM_OUTARG_VT
: {
5744 LLVMArgInfo
*ainfo
= (LLVMArgInfo
*)ins
->inst_p0
;
5745 MonoType
*t
= mini_get_underlying_type (ins
->inst_vtype
);
5747 if (ainfo
->storage
== LLVMArgGsharedvtVariable
) {
5748 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
5750 if (var
&& var
->opcode
== OP_GSHAREDVT_LOCAL
) {
5751 addresses
[ins
->dreg
] = convert (ctx
, emit_gsharedvt_ldaddr (ctx
, var
->dreg
), LLVMPointerType (IntPtrType (), 0));
5753 g_assert (addresses
[ins
->sreg1
]);
5754 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5756 } else if (ainfo
->storage
== LLVMArgGsharedvtFixed
) {
5757 if (!addresses
[ins
->sreg1
]) {
5758 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5759 g_assert (values
[ins
->sreg1
]);
5761 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (LLVMTypeOf (addresses
[ins
->sreg1
]))), addresses
[ins
->sreg1
]);
5762 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5764 if (!addresses
[ins
->sreg1
]) {
5765 addresses
[ins
->sreg1
] = build_alloca (ctx
, t
);
5766 g_assert (values
[ins
->sreg1
]);
5767 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, t
)), addresses
[ins
->sreg1
]);
5769 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
5773 case OP_OBJC_GET_SELECTOR
: {
5774 const char *name
= (const char*)ins
->inst_p0
;
5777 if (!ctx
->module
->objc_selector_to_var
)
5778 ctx
->module
->objc_selector_to_var
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
5779 var
= g_hash_table_lookup (ctx
->module
->objc_selector_to_var
, name
);
5781 LLVMValueRef indexes
[16];
5783 LLVMValueRef name_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMArrayType (LLVMInt8Type (), strlen (name
) + 1), "@OBJC_METH_VAR_NAME");
5784 LLVMSetInitializer (name_var
, mono_llvm_create_constant_data_array ((const uint8_t*)name
, strlen (name
) + 1));
5785 LLVMSetLinkage (name_var
, LLVMPrivateLinkage
);
5786 LLVMSetSection (name_var
, "__TEXT,__objc_methname,cstring_literals");
5788 LLVMValueRef ref_var
= LLVMAddGlobal (ctx
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES");
5790 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5791 indexes
[1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5792 LLVMSetInitializer (ref_var
, LLVMConstGEP (name_var
, indexes
, 2));
5793 LLVMSetLinkage (ref_var
, LLVMPrivateLinkage
);
5794 LLVMSetExternallyInitialized (ref_var
, TRUE
);
5795 LLVMSetSection (ref_var
, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5796 LLVMSetAlignment (ref_var
, sizeof (mgreg_t
));
5798 g_hash_table_insert (ctx
->module
->objc_selector_to_var
, g_strdup (name
), ref_var
);
5802 values
[ins
->dreg
] = LLVMBuildLoad (builder
, var
, "");
5809 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5811 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
5814 case OP_LOADX_MEMBASE
: {
5815 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
5818 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5819 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
5822 case OP_STOREX_MEMBASE
: {
5823 LLVMTypeRef t
= LLVMTypeOf (values
[ins
->sreg1
]);
5826 dest
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
5827 mono_llvm_build_aligned_store (builder
, values
[ins
->sreg1
], dest
, FALSE
, 1);
5834 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
5838 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
5844 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
5848 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
5852 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
5856 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
5859 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
5862 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
5865 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
5869 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, "");
5880 LLVMValueRef v
= NULL
;
5882 switch (ins
->opcode
) {
5887 t
= LLVMVectorType (LLVMInt32Type (), 4);
5888 rt
= LLVMVectorType (LLVMFloatType (), 4);
5894 t
= LLVMVectorType (LLVMInt64Type (), 2);
5895 rt
= LLVMVectorType (LLVMDoubleType (), 2);
5898 t
= LLVMInt32Type ();
5899 rt
= LLVMInt32Type ();
5900 g_assert_not_reached ();
5903 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
5904 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
5905 switch (ins
->opcode
) {
5908 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
5912 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
5916 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
5920 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
5923 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
5929 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntULT
, lhs
, rhs
, "");
5930 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5936 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntUGT
, lhs
, rhs
, "");
5937 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5941 LLVMValueRef cmp
= LLVMBuildICmp (builder
, LLVMIntSLT
, lhs
, rhs
, "");
5942 values
[ins
->dreg
] = LLVMBuildSelect (builder
, cmp
, lhs
, rhs
, "");
5959 case OP_PADDB_SAT_UN
:
5960 case OP_PADDW_SAT_UN
:
5961 case OP_PSUBB_SAT_UN
:
5962 case OP_PSUBW_SAT_UN
:
5970 case OP_PMULW_HIGH_UN
: {
5971 LLVMValueRef args
[2];
5976 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
5983 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntEQ
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
5987 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildICmp (builder
, LLVMIntSGT
, lhs
, rhs
, ""), LLVMTypeOf (lhs
), "");
5995 case OP_EXTRACTX_U2
:
5997 case OP_EXTRACT_U1
: {
5999 gboolean zext
= FALSE
;
6001 t
= simd_op_to_llvm_type (ins
->opcode
);
6003 switch (ins
->opcode
) {
6011 case OP_EXTRACTX_U2
:
6016 t
= LLVMInt32Type ();
6017 g_assert_not_reached ();
6020 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
6021 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
6023 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
6032 case OP_EXPAND_R8
: {
6033 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6034 LLVMValueRef mask
[16], v
;
6037 for (i
= 0; i
< 16; ++i
)
6038 mask
[i
] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
6040 v
= convert (ctx
, values
[ins
->sreg1
], LLVMGetElementType (t
));
6042 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, LLVMConstNull (t
), v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6043 values
[ins
->dreg
] = LLVMBuildShuffleVector (builder
, values
[ins
->dreg
], LLVMGetUndef (t
), LLVMConstVector (mask
, LLVMGetVectorSize (t
)), "");
6048 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6051 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6054 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6057 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6060 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6063 values
[ins
->dreg
] = LLVMBuildInsertElement (builder
, values
[ins
->sreg1
], convert (ctx
, values
[ins
->sreg2
], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), dname
);
6074 case OP_EXTRACT_MASK
:
6081 v
= convert (ctx
, values
[ins
->sreg1
], simd_op_to_llvm_type (ins
->opcode
));
6083 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), &v
, 1, dname
);
6088 LLVMRealPredicate op
;
6090 switch (ins
->inst_c0
) {
6100 case SIMD_COMP_UNORD
:
6116 g_assert_not_reached ();
6119 LLVMValueRef cmp
= LLVMBuildFCmp (builder
, op
, lhs
, rhs
, "");
6120 if (ins
->opcode
== OP_COMPPD
)
6121 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs
), "");
6123 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, LLVMBuildSExt (builder
, cmp
, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs
), "");
6127 /* This is only used for implementing shifts by non-immediate */
6128 values
[ins
->dreg
] = lhs
;
6139 LLVMValueRef args
[3];
6142 args
[1] = LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
6144 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6155 case OP_PSHLQ_REG
: {
6156 LLVMValueRef args
[3];
6159 args
[1] = values
[ins
->sreg2
];
6161 values
[ins
->dreg
] = LLVMBuildCall (builder
, get_intrinsic (ctx
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
6168 case OP_PSHUFLEW_LOW
:
6169 case OP_PSHUFLEW_HIGH
: {
6171 LLVMValueRef v1
= NULL
, v2
= NULL
, mask_values
[16];
6172 int i
, mask_size
= 0;
6173 int imask
= ins
->inst_c0
;
6175 /* Convert the x86 shuffle mask to LLVM's */
6176 switch (ins
->opcode
) {
6179 mask
[0] = ((imask
>> 0) & 3);
6180 mask
[1] = ((imask
>> 2) & 3);
6181 mask
[2] = ((imask
>> 4) & 3) + 4;
6182 mask
[3] = ((imask
>> 6) & 3) + 4;
6183 v1
= values
[ins
->sreg1
];
6184 v2
= values
[ins
->sreg2
];
6188 mask
[0] = ((imask
>> 0) & 1);
6189 mask
[1] = ((imask
>> 1) & 1) + 2;
6190 v1
= values
[ins
->sreg1
];
6191 v2
= values
[ins
->sreg2
];
6193 case OP_PSHUFLEW_LOW
:
6195 mask
[0] = ((imask
>> 0) & 3);
6196 mask
[1] = ((imask
>> 2) & 3);
6197 mask
[2] = ((imask
>> 4) & 3);
6198 mask
[3] = ((imask
>> 6) & 3);
6203 v1
= values
[ins
->sreg1
];
6204 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6206 case OP_PSHUFLEW_HIGH
:
6212 mask
[4] = 4 + ((imask
>> 0) & 3);
6213 mask
[5] = 4 + ((imask
>> 2) & 3);
6214 mask
[6] = 4 + ((imask
>> 4) & 3);
6215 mask
[7] = 4 + ((imask
>> 6) & 3);
6216 v1
= values
[ins
->sreg1
];
6217 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6221 mask
[0] = ((imask
>> 0) & 3);
6222 mask
[1] = ((imask
>> 2) & 3);
6223 mask
[2] = ((imask
>> 4) & 3);
6224 mask
[3] = ((imask
>> 6) & 3);
6225 v1
= values
[ins
->sreg1
];
6226 v2
= LLVMGetUndef (LLVMTypeOf (v1
));
6229 g_assert_not_reached ();
6231 for (i
= 0; i
< mask_size
; ++i
)
6232 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6234 values
[ins
->dreg
] =
6235 LLVMBuildShuffleVector (builder
, v1
, v2
,
6236 LLVMConstVector (mask_values
, mask_size
), dname
);
6240 case OP_UNPACK_LOWB
:
6241 case OP_UNPACK_LOWW
:
6242 case OP_UNPACK_LOWD
:
6243 case OP_UNPACK_LOWQ
:
6244 case OP_UNPACK_LOWPS
:
6245 case OP_UNPACK_LOWPD
:
6246 case OP_UNPACK_HIGHB
:
6247 case OP_UNPACK_HIGHW
:
6248 case OP_UNPACK_HIGHD
:
6249 case OP_UNPACK_HIGHQ
:
6250 case OP_UNPACK_HIGHPS
:
6251 case OP_UNPACK_HIGHPD
: {
6253 LLVMValueRef mask_values
[16];
6254 int i
, mask_size
= 0;
6255 gboolean low
= FALSE
;
6257 switch (ins
->opcode
) {
6258 case OP_UNPACK_LOWB
:
6262 case OP_UNPACK_LOWW
:
6266 case OP_UNPACK_LOWD
:
6267 case OP_UNPACK_LOWPS
:
6271 case OP_UNPACK_LOWQ
:
6272 case OP_UNPACK_LOWPD
:
6276 case OP_UNPACK_HIGHB
:
6279 case OP_UNPACK_HIGHW
:
6282 case OP_UNPACK_HIGHD
:
6283 case OP_UNPACK_HIGHPS
:
6286 case OP_UNPACK_HIGHQ
:
6287 case OP_UNPACK_HIGHPD
:
6291 g_assert_not_reached ();
6295 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6297 mask
[(i
* 2) + 1] = mask_size
+ i
;
6300 for (i
= 0; i
< (mask_size
/ 2); ++i
) {
6301 mask
[(i
* 2)] = (mask_size
/ 2) + i
;
6302 mask
[(i
* 2) + 1] = mask_size
+ (mask_size
/ 2) + i
;
6306 for (i
= 0; i
< mask_size
; ++i
)
6307 mask_values
[i
] = LLVMConstInt (LLVMInt32Type (), mask
[i
], FALSE
);
6309 values
[ins
->dreg
] =
6310 LLVMBuildShuffleVector (builder
, values
[ins
->sreg1
], values
[ins
->sreg2
],
6311 LLVMConstVector (mask_values
, mask_size
), dname
);
6316 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6317 LLVMValueRef v
, val
;
6319 v
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6320 val
= LLVMConstNull (t
);
6321 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6322 val
= LLVMBuildInsertElement (builder
, val
, v
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), dname
);
6324 values
[ins
->dreg
] = val
;
6328 case OP_DUPPS_HIGH
: {
6329 LLVMTypeRef t
= simd_op_to_llvm_type (ins
->opcode
);
6330 LLVMValueRef v1
, v2
, val
;
6333 if (ins
->opcode
== OP_DUPPS_LOW
) {
6334 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6335 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6337 v1
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6338 v2
= LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6340 val
= LLVMConstNull (t
);
6341 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), "");
6342 val
= LLVMBuildInsertElement (builder
, val
, v1
, LLVMConstInt (LLVMInt32Type (), 1, FALSE
), "");
6343 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 2, FALSE
), "");
6344 val
= LLVMBuildInsertElement (builder
, val
, v2
, LLVMConstInt (LLVMInt32Type (), 3, FALSE
), "");
6346 values
[ins
->dreg
] = val
;
6356 * EXCEPTION HANDLING
6358 case OP_IMPLICIT_EXCEPTION
:
6359 /* This marks a place where an implicit exception can happen */
6360 if (bb
->region
!= -1)
6361 set_failure (ctx
, "implicit-exception");
6365 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
6366 if (ctx
->llvm_only
) {
6367 emit_llvmonly_throw (ctx
, bb
, rethrow
, lhs
);
6368 has_terminator
= TRUE
;
6369 ctx
->unreachable
[bb
->block_num
] = TRUE
;
6371 emit_throw (ctx
, bb
, rethrow
, lhs
);
6372 builder
= ctx
->builder
;
6376 case OP_CALL_HANDLER
: {
6378 * We don't 'call' handlers, but instead simply branch to them.
6379 * The code generated by ENDFINALLY will branch back to us.
6381 LLVMBasicBlockRef noex_bb
;
6383 BBInfo
*info
= &bblocks
[ins
->inst_target_bb
->block_num
];
6385 bb_list
= info
->call_handler_return_bbs
;
6388 * Set the indicator variable for the finally clause.
6390 lhs
= info
->finally_ind
;
6392 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
6394 /* Branch to the finally clause */
6395 LLVMBuildBr (builder
, info
->call_handler_target_bb
);
6397 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
6398 info
->call_handler_return_bbs
= g_slist_append_mempool (cfg
->mempool
, info
->call_handler_return_bbs
, noex_bb
);
6400 builder
= ctx
->builder
= create_builder (ctx
);
6401 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
6403 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
6406 case OP_START_HANDLER
: {
6409 case OP_ENDFINALLY
: {
6410 LLVMBasicBlockRef resume_bb
;
6411 MonoBasicBlock
*handler_bb
;
6412 LLVMValueRef val
, switch_ins
, callee
;
6416 handler_bb
= (MonoBasicBlock
*)g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
6417 g_assert (handler_bb
);
6418 info
= &bblocks
[handler_bb
->block_num
];
6419 lhs
= info
->finally_ind
;
6422 bb_list
= info
->call_handler_return_bbs
;
6424 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
6426 /* Load the finally variable */
6427 val
= LLVMBuildLoad (builder
, lhs
, "");
6429 /* Reset the variable */
6430 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
6432 /* Branch to either resume_bb, or to the bblocks in bb_list */
6433 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
6435 * The other targets are added at the end to handle OP_CALL_HANDLER
6436 * opcodes processed later.
6438 info
->endfinally_switch_ins_list
= g_slist_append_mempool (cfg
->mempool
, info
->endfinally_switch_ins_list
, switch_ins
);
6440 builder
= ctx
->builder
= create_builder (ctx
);
6441 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
6443 if (ctx
->llvm_only
) {
6444 emit_resume_eh (ctx
, bb
);
6446 if (ctx
->cfg
->compile_aot
) {
6447 callee
= get_callee (ctx
, LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
), MONO_PATCH_INFO_INTERNAL_METHOD
, "llvm_resume_unwind_trampoline");
6449 #if LLVM_API_VERSION > 100
6450 MonoJitICallInfo
*info
;
6452 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6454 gpointer target
= (void*)info
->func
;
6455 LLVMTypeRef icall_sig
= LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
);
6456 callee
= emit_jit_callee (ctx
, "llvm_resume_unwind_trampoline", icall_sig
, target
);
6458 callee
= LLVMGetNamedFunction (ctx
->lmodule
, "llvm_resume_unwind_trampoline");
6461 LLVMBuildCall (builder
, callee
, NULL
, 0, "");
6462 LLVMBuildUnreachable (builder
);
6465 has_terminator
= TRUE
;
6468 case OP_IL_SEQ_POINT
:
6473 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
6474 set_failure (ctx
, reason
);
6482 /* Convert the value to the type required by phi nodes */
6483 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && ctx
->vreg_types
[ins
->dreg
]) {
6484 if (!values
[ins
->dreg
])
6486 values
[ins
->dreg
] = addresses
[ins
->dreg
];
6488 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], ctx
->vreg_types
[ins
->dreg
]);
6491 /* Add stores for volatile variables */
6492 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
6493 emit_volatile_store (ctx
, ins
->dreg
);
6499 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0)) {
6500 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
6503 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
) {
6504 emit_dbg_loc (ctx
, builder
, cfg
->header
->code
+ cfg
->header
->code_size
- 1);
6505 LLVMBuildRetVoid (builder
);
6508 if (bb
== cfg
->bb_entry
)
6509 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
6513 * mono_llvm_check_method_supported:
6515 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6516 * compiling a method twice.
6519 mono_llvm_check_method_supported (MonoCompile
*cfg
)
6526 if (cfg
->method
->save_lmf
) {
6527 cfg
->exception_message
= g_strdup ("lmf");
6528 cfg
->disable_llvm
= TRUE
;
6530 if (cfg
->disable_llvm
)
6534 * Nested clauses where one of the clauses is a finally clause is
6535 * not supported, because LLVM can't figure out the control flow,
6536 * probably because we resume exception handling by calling our
6537 * own function instead of using the 'resume' llvm instruction.
6539 for (i
= 0; i
< cfg
->header
->num_clauses
; ++i
) {
6540 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
6541 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[i
];
6542 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[j
];
6544 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6545 if (i
!= j
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
6546 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6547 cfg
->exception_message
= g_strdup ("nested clauses");
6548 cfg
->disable_llvm
= TRUE
;
6553 if (cfg
->disable_llvm
)
6557 if (cfg
->method
->dynamic
) {
6558 cfg
->exception_message
= g_strdup ("dynamic.");
6559 cfg
->disable_llvm
= TRUE
;
6561 if (cfg
->disable_llvm
)
6565 static LLVMCallInfo
*
6566 get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
6568 LLVMCallInfo
*linfo
;
6571 if (cfg
->gsharedvt
&& cfg
->llvm_only
&& mini_is_gsharedvt_variable_signature (sig
)) {
6575 * Gsharedvt methods have the following calling convention:
6576 * - all arguments are passed by ref, even non generic ones
6577 * - the return value is returned by ref too, using a vret
6578 * argument passed after 'this'.
6580 n
= sig
->param_count
+ sig
->hasthis
;
6581 linfo
= (LLVMCallInfo
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
6585 linfo
->args
[pindex
++].storage
= LLVMArgNormal
;
6587 if (sig
->ret
->type
!= MONO_TYPE_VOID
) {
6588 if (mini_is_gsharedvt_variable_type (sig
->ret
))
6589 linfo
->ret
.storage
= LLVMArgGsharedvtVariable
;
6590 else if (mini_type_is_vtype (sig
->ret
))
6591 linfo
->ret
.storage
= LLVMArgGsharedvtFixedVtype
;
6593 linfo
->ret
.storage
= LLVMArgGsharedvtFixed
;
6594 linfo
->vret_arg_index
= pindex
;
6596 linfo
->ret
.storage
= LLVMArgNone
;
6599 for (i
= 0; i
< sig
->param_count
; ++i
) {
6600 if (sig
->params
[i
]->byref
)
6601 linfo
->args
[pindex
].storage
= LLVMArgNormal
;
6602 else if (mini_is_gsharedvt_variable_type (sig
->params
[i
]))
6603 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtVariable
;
6604 else if (mini_type_is_vtype (sig
->params
[i
]))
6605 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixedVtype
;
6607 linfo
->args
[pindex
].storage
= LLVMArgGsharedvtFixed
;
6608 linfo
->args
[pindex
].type
= sig
->params
[i
];
6615 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
6616 for (i
= 0; i
< sig
->param_count
; ++i
)
6617 linfo
->args
[i
+ sig
->hasthis
].type
= sig
->params
[i
];
6623 emit_method_inner (EmitContext
*ctx
);
6626 free_ctx (EmitContext
*ctx
)
6630 g_free (ctx
->values
);
6631 g_free (ctx
->addresses
);
6632 g_free (ctx
->vreg_types
);
6633 g_free (ctx
->vreg_cli_types
);
6634 g_free (ctx
->is_dead
);
6635 g_free (ctx
->unreachable
);
6636 g_ptr_array_free (ctx
->phi_values
, TRUE
);
6637 g_free (ctx
->bblocks
);
6638 g_hash_table_destroy (ctx
->region_to_handler
);
6639 g_hash_table_destroy (ctx
->clause_to_handler
);
6640 g_hash_table_destroy (ctx
->jit_callees
);
6642 GHashTableIter iter
;
6643 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
6644 while (g_hash_table_iter_next (&iter
, NULL
, (gpointer
)&l
))
6647 g_hash_table_destroy (ctx
->method_to_callers
);
6649 g_free (ctx
->method_name
);
6650 g_ptr_array_free (ctx
->bblock_list
, TRUE
);
6652 for (l
= ctx
->builders
; l
; l
= l
->next
) {
6653 LLVMBuilderRef builder
= (LLVMBuilderRef
)l
->data
;
6654 LLVMDisposeBuilder (builder
);
6661 * mono_llvm_emit_method:
6663 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6666 mono_llvm_emit_method (MonoCompile
*cfg
)
6670 gboolean is_linkonce
= FALSE
;
6673 /* The code below might acquire the loader lock, so use it for global locking */
6674 mono_loader_lock ();
6676 /* Used to communicate with the callbacks */
6677 mono_native_tls_set_value (current_cfg_tls_id
, cfg
);
6679 ctx
= g_new0 (EmitContext
, 1);
6681 ctx
->mempool
= cfg
->mempool
;
6684 * This maps vregs to the LLVM instruction defining them
6686 ctx
->values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6688 * This maps vregs for volatile variables to the LLVM instruction defining their
6691 ctx
->addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
6692 ctx
->vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
6693 ctx
->vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
6694 ctx
->phi_values
= g_ptr_array_sized_new (256);
6696 * This signals whenever the vreg was defined by a phi node with no input vars
6697 * (i.e. all its input bblocks end with NOT_REACHABLE).
6699 ctx
->is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
6700 /* Whenever the bblock is unreachable */
6701 ctx
->unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
6702 ctx
->bblock_list
= g_ptr_array_sized_new (256);
6704 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
6705 ctx
->clause_to_handler
= g_hash_table_new (NULL
, NULL
);
6706 ctx
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
6707 ctx
->jit_callees
= g_hash_table_new (NULL
, NULL
);
6708 if (cfg
->compile_aot
) {
6709 ctx
->module
= &aot_module
;
6713 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6714 * linkage for them. This requires the following:
6715 * - the method needs to have a unique mangled name
6716 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6718 is_linkonce
= ctx
->module
->llvm_only
&& ctx
->module
->static_link
&& mono_aot_is_linkonce_method (cfg
->method
);
6720 method_name
= mono_aot_get_mangled_method_name (cfg
->method
);
6722 is_linkonce
= FALSE
;
6725 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6727 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6731 method_name
= mono_aot_get_method_name (cfg
);
6732 cfg
->llvm_method_name
= g_strdup (method_name
);
6734 init_jit_module (cfg
->domain
);
6735 ctx
->module
= (MonoLLVMModule
*)domain_jit_info (cfg
->domain
)->llvm_module
;
6736 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
6738 ctx
->method_name
= method_name
;
6739 ctx
->is_linkonce
= is_linkonce
;
6741 #if LLVM_API_VERSION > 100
6742 if (cfg
->compile_aot
)
6743 ctx
->lmodule
= ctx
->module
->lmodule
;
6745 ctx
->lmodule
= LLVMModuleCreateWithName ("jit-module");
6747 ctx
->lmodule
= ctx
->module
->lmodule
;
6749 ctx
->llvm_only
= ctx
->module
->llvm_only
;
6751 emit_method_inner (ctx
);
6753 if (!ctx_ok (ctx
)) {
6755 /* Need to add unused phi nodes as they can be referenced by other values */
6756 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, "PHI_BB");
6757 LLVMBuilderRef builder
;
6759 builder
= create_builder (ctx
);
6760 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
6762 for (i
= 0; i
< ctx
->phi_values
->len
; ++i
) {
6763 LLVMValueRef v
= (LLVMValueRef
)g_ptr_array_index (ctx
->phi_values
, i
);
6764 if (LLVMGetInstructionParent (v
) == NULL
)
6765 LLVMInsertIntoBuilder (builder
, v
);
6768 LLVMDeleteFunction (ctx
->lmethod
);
6774 mono_native_tls_set_value (current_cfg_tls_id
, NULL
);
6776 mono_loader_unlock ();
6780 emit_method_inner (EmitContext
*ctx
)
6782 MonoCompile
*cfg
= ctx
->cfg
;
6783 MonoMethodSignature
*sig
;
6785 LLVMTypeRef method_type
;
6786 LLVMValueRef method
= NULL
;
6787 LLVMValueRef
*values
= ctx
->values
;
6788 int i
, max_block_num
, bb_index
;
6789 gboolean last
= FALSE
;
6790 LLVMCallInfo
*linfo
;
6791 LLVMModuleRef lmodule
= ctx
->lmodule
;
6793 GPtrArray
*bblock_list
= ctx
->bblock_list
;
6794 MonoMethodHeader
*header
;
6795 MonoExceptionClause
*clause
;
6798 if (cfg
->gsharedvt
&& !cfg
->llvm_only
) {
6799 set_failure (ctx
, "gsharedvt");
6805 static int count
= 0;
6808 if (g_getenv ("LLVM_COUNT")) {
6809 if (count
== atoi (g_getenv ("LLVM_COUNT"))) {
6810 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
6814 if (count
> atoi (g_getenv ("LLVM_COUNT"))) {
6815 set_failure (ctx
, "count");
6822 sig
= mono_method_signature (cfg
->method
);
6825 linfo
= get_llvm_call_info (cfg
, sig
);
6831 linfo
->rgctx_arg
= TRUE
;
6832 ctx
->method_type
= method_type
= sig_to_llvm_sig_full (ctx
, sig
, linfo
);
6836 method
= LLVMAddFunction (lmodule
, ctx
->method_name
, method_type
);
6837 ctx
->lmethod
= method
;
6839 if (!cfg
->llvm_only
)
6840 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
6841 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
6843 LLVMAddFunctionAttr (method
, LLVMUWTable
);
6845 if (cfg
->compile_aot
) {
6846 LLVMSetLinkage (method
, LLVMInternalLinkage
);
6847 if (ctx
->module
->external_symbols
) {
6848 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6849 LLVMSetVisibility (method
, LLVMHiddenVisibility
);
6851 if (ctx
->is_linkonce
) {
6852 LLVMSetLinkage (method
, LLVMLinkOnceAnyLinkage
);
6853 LLVMSetVisibility (method
, LLVMDefaultVisibility
);
6856 #if LLVM_API_VERSION > 100
6857 LLVMSetLinkage (method
, LLVMExternalLinkage
);
6859 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
6863 if (cfg
->method
->save_lmf
&& !cfg
->llvm_only
) {
6864 set_failure (ctx
, "lmf");
6868 if (sig
->pinvoke
&& cfg
->method
->wrapper_type
!= MONO_WRAPPER_RUNTIME_INVOKE
&& !cfg
->llvm_only
) {
6869 set_failure (ctx
, "pinvoke signature");
6873 header
= cfg
->header
;
6874 for (i
= 0; i
< header
->num_clauses
; ++i
) {
6875 clause
= &header
->clauses
[i
];
6876 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
) {
6877 set_failure (ctx
, "non-finally/catch clause.");
6881 if (header
->num_clauses
|| (cfg
->method
->iflags
& METHOD_IMPL_ATTRIBUTE_NOINLINING
) || cfg
->no_inline
)
6882 /* We can't handle inlined methods with clauses */
6883 LLVMAddFunctionAttr (method
, LLVMNoInlineAttribute
);
6885 if (linfo
->rgctx_arg
) {
6886 ctx
->rgctx_arg
= LLVMGetParam (method
, linfo
->rgctx_arg_pindex
);
6887 ctx
->rgctx_arg_pindex
= linfo
->rgctx_arg_pindex
;
6889 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6890 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6891 * CC_X86_64_Mono in X86CallingConv.td.
6893 if (!ctx
->llvm_only
)
6894 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
6895 LLVMSetValueName (ctx
->rgctx_arg
, "rgctx");
6897 ctx
->rgctx_arg_pindex
= -1;
6899 if (cfg
->vret_addr
) {
6900 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, linfo
->vret_arg_pindex
);
6901 LLVMSetValueName (values
[cfg
->vret_addr
->dreg
], "vret");
6902 if (linfo
->ret
.storage
== LLVMArgVtypeByRef
) {
6903 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMStructRetAttribute
);
6904 LLVMAddAttribute (LLVMGetParam (method
, linfo
->vret_arg_pindex
), LLVMNoAliasAttribute
);
6909 ctx
->this_arg_pindex
= linfo
->this_arg_pindex
;
6910 ctx
->this_arg
= LLVMGetParam (method
, linfo
->this_arg_pindex
);
6911 values
[cfg
->args
[0]->dreg
] = ctx
->this_arg
;
6912 LLVMSetValueName (values
[cfg
->args
[0]->dreg
], "this");
6915 names
= g_new (char *, sig
->param_count
);
6916 mono_method_get_param_names (cfg
->method
, (const char **) names
);
6918 /* Set parameter names/attributes */
6919 for (i
= 0; i
< sig
->param_count
; ++i
) {
6920 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
6922 int pindex
= ainfo
->pindex
+ ainfo
->ndummy_fpargs
;
6925 for (j
= 0; j
< ainfo
->ndummy_fpargs
; ++j
) {
6926 name
= g_strdup_printf ("dummy_%d_%d", i
, j
);
6927 LLVMSetValueName (LLVMGetParam (method
, ainfo
->pindex
+ j
), name
);
6931 if (ainfo
->storage
== LLVMArgVtypeInReg
&& ainfo
->pair_storage
[0] == LLVMArgNone
&& ainfo
->pair_storage
[1] == LLVMArgNone
)
6934 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
6935 if (ainfo
->storage
== LLVMArgGsharedvtFixed
|| ainfo
->storage
== LLVMArgGsharedvtFixedVtype
) {
6936 if (names
[i
] && names
[i
][0] != '\0')
6937 name
= g_strdup_printf ("p_arg_%s", names
[i
]);
6939 name
= g_strdup_printf ("p_arg_%d", i
);
6941 if (names
[i
] && names
[i
][0] != '\0')
6942 name
= g_strdup_printf ("arg_%s", names
[i
]);
6944 name
= g_strdup_printf ("arg_%d", i
);
6946 LLVMSetValueName (values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
], name
);
6948 if (ainfo
->storage
== LLVMArgVtypeByVal
)
6949 LLVMAddAttribute (LLVMGetParam (method
, pindex
), LLVMByValAttribute
);
6951 if (ainfo
->storage
== LLVMArgVtypeByRef
) {
6953 cfg
->args
[i
+ sig
->hasthis
]->opcode
= OP_VTARG_ADDR
;
6958 if (ctx
->module
->emit_dwarf
&& cfg
->compile_aot
&& mono_debug_enabled ()) {
6959 ctx
->minfo
= mono_debug_lookup_method (cfg
->method
);
6960 ctx
->dbg_md
= emit_dbg_subprogram (ctx
, cfg
, method
, ctx
->method_name
);
6964 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
6965 max_block_num
= MAX (max_block_num
, bb
->block_num
);
6966 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
6968 /* Add branches between non-consecutive bblocks */
6969 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
6970 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
6971 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
6973 MonoInst
*inst
= (MonoInst
*)mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
6974 inst
->opcode
= OP_BR
;
6975 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
6976 mono_bblock_add_inst (bb
, inst
);
6981 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6982 * was later optimized away, so clear these flags, and add them back for the still
6983 * present OP_LDADDR instructions.
6985 for (i
= 0; i
< cfg
->next_vreg
; ++i
) {
6988 ins
= get_vreg_to_inst (cfg
, i
);
6989 if (ins
&& ins
!= cfg
->rgctx_var
)
6990 ins
->flags
&= ~MONO_INST_INDIRECT
;
6994 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6996 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
6998 LLVMBuilderRef builder
;
7000 char dname_buf
[128];
7002 builder
= create_builder (ctx
);
7004 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
7005 switch (ins
->opcode
) {
7010 LLVMTypeRef phi_type
= llvm_type_to_stack_type (cfg
, type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
7015 if (ins
->opcode
== OP_VPHI
) {
7016 /* Treat valuetype PHI nodes as operating on the address itself */
7017 g_assert (ins
->klass
);
7018 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
7022 * Have to precreate these, as they can be referenced by
7023 * earlier instructions.
7025 sprintf (dname_buf
, "t%d", ins
->dreg
);
7027 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
7029 if (ins
->opcode
== OP_VPHI
)
7030 ctx
->addresses
[ins
->dreg
] = values
[ins
->dreg
];
7032 g_ptr_array_add (ctx
->phi_values
, values
[ins
->dreg
]);
7035 * Set the expected type of the incoming arguments since these have
7036 * to have the same type.
7038 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
7039 int sreg1
= ins
->inst_phi_args
[i
+ 1];
7042 ctx
->vreg_types
[sreg1
] = phi_type
;
7047 ((MonoInst
*)ins
->inst_p0
)->flags
|= MONO_INST_INDIRECT
;
7056 * Create an ordering for bblocks, use the depth first order first, then
7057 * put the exception handling bblocks last.
7059 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
7060 bb
= cfg
->bblocks
[bb_index
];
7061 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
7062 g_ptr_array_add (bblock_list
, bb
);
7063 bblocks
[bb
->block_num
].added
= TRUE
;
7067 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7068 if (!bblocks
[bb
->block_num
].added
)
7069 g_ptr_array_add (bblock_list
, bb
);
7073 * Second pass: generate code.
7076 LLVMBuilderRef entry_builder
= create_builder (ctx
);
7077 LLVMBasicBlockRef entry_bb
= get_bb (ctx
, cfg
->bb_entry
);
7078 LLVMPositionBuilderAtEnd (entry_builder
, entry_bb
);
7079 emit_entry_bb (ctx
, entry_builder
);
7081 // Make landing pads first
7082 ctx
->exc_meta
= g_hash_table_new_full (NULL
, NULL
, NULL
, NULL
);
7084 if (ctx
->llvm_only
) {
7085 size_t group_index
= 0;
7086 while (group_index
< cfg
->header
->num_clauses
) {
7088 size_t cursor
= group_index
;
7089 while (cursor
< cfg
->header
->num_clauses
&&
7090 CLAUSE_START (&cfg
->header
->clauses
[cursor
]) == CLAUSE_START (&cfg
->header
->clauses
[group_index
]) &&
7091 CLAUSE_END (&cfg
->header
->clauses
[cursor
]) == CLAUSE_END (&cfg
->header
->clauses
[group_index
])) {
7096 LLVMBasicBlockRef lpad_bb
= emit_landing_pad (ctx
, group_index
, count
);
7097 intptr_t key
= CLAUSE_END (&cfg
->header
->clauses
[group_index
]);
7098 g_hash_table_insert (ctx
->exc_meta
, (gpointer
)key
, lpad_bb
);
7100 group_index
= cursor
;
7104 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
7105 bb
= (MonoBasicBlock
*)g_ptr_array_index (bblock_list
, bb_index
);
7107 // Prune unreachable mono BBs.
7108 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
7111 process_bb (ctx
, bb
);
7115 g_hash_table_destroy (ctx
->exc_meta
);
7117 mono_memory_barrier ();
7119 /* Add incoming phi values */
7120 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7121 GSList
*l
, *ins_list
;
7123 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7125 for (l
= ins_list
; l
; l
= l
->next
) {
7126 PhiNode
*node
= (PhiNode
*)l
->data
;
7127 MonoInst
*phi
= node
->phi
;
7128 int sreg1
= node
->sreg
;
7129 LLVMBasicBlockRef in_bb
;
7134 in_bb
= get_end_bb (ctx
, node
->in_bb
);
7136 if (ctx
->unreachable
[node
->in_bb
->block_num
])
7139 if (!values
[sreg1
]) {
7140 /* Can happen with values in EH clauses */
7141 set_failure (ctx
, "incoming phi sreg1");
7145 if (phi
->opcode
== OP_VPHI
) {
7146 g_assert (LLVMTypeOf (ctx
->addresses
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7147 LLVMAddIncoming (values
[phi
->dreg
], &ctx
->addresses
[sreg1
], &in_bb
, 1);
7149 if (LLVMTypeOf (values
[sreg1
]) != LLVMTypeOf (values
[phi
->dreg
])) {
7150 set_failure (ctx
, "incoming phi arg type mismatch");
7153 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
7154 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
7159 /* Nullify empty phi instructions */
7160 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7161 GSList
*l
, *ins_list
;
7163 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
7165 for (l
= ins_list
; l
; l
= l
->next
) {
7166 PhiNode
*node
= (PhiNode
*)l
->data
;
7167 MonoInst
*phi
= node
->phi
;
7168 LLVMValueRef phi_ins
= values
[phi
->dreg
];
7171 /* Already removed */
7174 if (LLVMCountIncoming (phi_ins
) == 0) {
7175 mono_llvm_replace_uses_of (phi_ins
, LLVMConstNull (LLVMTypeOf (phi_ins
)));
7176 LLVMInstructionEraseFromParent (phi_ins
);
7177 values
[phi
->dreg
] = NULL
;
7182 /* Create the SWITCH statements for ENDFINALLY instructions */
7183 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
7184 BBInfo
*info
= &bblocks
[bb
->block_num
];
7186 for (l
= info
->endfinally_switch_ins_list
; l
; l
= l
->next
) {
7187 LLVMValueRef switch_ins
= (LLVMValueRef
)l
->data
;
7188 GSList
*bb_list
= info
->call_handler_return_bbs
;
7190 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
7191 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), (LLVMBasicBlockRef
)(g_slist_nth (bb_list
, i
)->data
));
7195 /* Initialize the method if needed */
7196 if (cfg
->compile_aot
&& ctx
->llvm_only
) {
7197 // FIXME: Add more shared got entries
7198 ctx
->builder
= create_builder (ctx
);
7199 LLVMPositionBuilderAtEnd (ctx
->builder
, ctx
->init_bb
);
7201 ctx
->module
->max_method_idx
= MAX (ctx
->module
->max_method_idx
, cfg
->method_index
);
7203 // FIXME: beforefieldinit
7204 if (ctx
->has_got_access
|| mono_class_get_cctor (cfg
->method
->klass
)) {
7206 * linkonce methods shouldn't have initialization,
7207 * because they might belong to assemblies which
7208 * haven't been loaded yet.
7210 g_assert (!ctx
->is_linkonce
);
7211 emit_init_method (ctx
);
7213 LLVMBuildBr (ctx
->builder
, ctx
->inited_bb
);
7217 if (cfg
->llvm_only
) {
7218 GHashTableIter iter
;
7220 GSList
*callers
, *l
, *l2
;
7223 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7224 * We can't do this earlier, as it contains llvm instructions which can be
7225 * freed if compilation fails.
7226 * FIXME: Get rid of this when all methods can be llvm compiled.
7228 g_hash_table_iter_init (&iter
, ctx
->method_to_callers
);
7229 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
7230 for (l
= callers
; l
; l
= l
->next
) {
7231 l2
= (GSList
*)g_hash_table_lookup (ctx
->module
->method_to_callers
, method
);
7232 l2
= g_slist_prepend (l2
, l
->data
);
7233 g_hash_table_insert (ctx
->module
->method_to_callers
, method
, l2
);
7238 if (cfg
->verbose_level
> 1)
7239 mono_llvm_dump_value (method
);
7241 if (cfg
->compile_aot
&& !cfg
->llvm_only
)
7242 mark_as_used (ctx
->module
, method
);
7244 if (!cfg
->llvm_only
) {
7245 LLVMValueRef md_args
[16];
7246 LLVMValueRef md_node
;
7249 if (cfg
->compile_aot
)
7250 method_index
= mono_aot_get_method_index (cfg
->orig_method
);
7253 md_args
[0] = LLVMMDString (ctx
->method_name
, strlen (ctx
->method_name
));
7254 md_args
[1] = LLVMConstInt (LLVMInt32Type (), method_index
, FALSE
);
7255 md_node
= LLVMMDNode (md_args
, 2);
7256 LLVMAddNamedMetadataOperand (lmodule
, "mono.function_indexes", md_node
);
7257 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7260 if (cfg
->compile_aot
) {
7261 /* Don't generate native code, keep the LLVM IR */
7262 if (cfg
->verbose_level
)
7263 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), ctx
->method_name
);
7265 #if LLVM_API_VERSION < 100
7266 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7267 int err
= LLVMVerifyFunction(ctx
->lmethod
, LLVMPrintMessageAction
);
7268 g_assert (err
== 0);
7271 //LLVMVerifyFunction(method, 0);
7272 #if LLVM_API_VERSION > 100
7273 MonoDomain
*domain
= mono_domain_get ();
7274 MonoJitDomainInfo
*domain_info
;
7275 int nvars
= g_hash_table_size (ctx
->jit_callees
);
7276 LLVMValueRef
*callee_vars
= g_new0 (LLVMValueRef
, nvars
);
7277 gpointer
*callee_addrs
= g_new0 (gpointer
, nvars
);
7278 GHashTableIter iter
;
7284 * Compute the addresses of the LLVM globals pointing to the
7285 * methods called by the current method. Pass it to the trampoline
7286 * code so it can update them after their corresponding method was
7289 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7291 while (g_hash_table_iter_next (&iter
, NULL
, (void**)&var
))
7292 callee_vars
[i
++] = var
;
7294 cfg
->native_code
= mono_llvm_compile_method (ctx
->module
->mono_ee
, ctx
->lmethod
, nvars
, callee_vars
, callee_addrs
, &eh_frame
);
7296 decode_llvm_eh_info (ctx
, eh_frame
);
7298 mono_domain_lock (domain
);
7299 domain_info
= domain_jit_info (domain
);
7300 if (!domain_info
->llvm_jit_callees
)
7301 domain_info
->llvm_jit_callees
= g_hash_table_new (NULL
, NULL
);
7302 g_hash_table_iter_init (&iter
, ctx
->jit_callees
);
7304 while (g_hash_table_iter_next (&iter
, (void**)&callee
, (void**)&var
)) {
7305 GSList
*addrs
= g_hash_table_lookup (domain_info
->llvm_jit_callees
, callee
);
7306 addrs
= g_slist_prepend (addrs
, callee_addrs
[i
]);
7307 g_hash_table_insert (domain_info
->llvm_jit_callees
, callee
, addrs
);
7310 mono_domain_unlock (domain
);
7312 mono_llvm_optimize_method (ctx
->module
->mono_ee
, ctx
->lmethod
);
7314 if (cfg
->verbose_level
> 1)
7315 mono_llvm_dump_value (ctx
->lmethod
);
7317 cfg
->native_code
= (unsigned char*)LLVMGetPointerToGlobal (ctx
->module
->ee
, ctx
->lmethod
);
7319 /* Set by emit_cb */
7320 g_assert (cfg
->code_len
);
7324 if (ctx
->module
->method_to_lmethod
)
7325 g_hash_table_insert (ctx
->module
->method_to_lmethod
, cfg
->method
, ctx
->lmethod
);
7326 if (ctx
->module
->idx_to_lmethod
)
7327 g_hash_table_insert (ctx
->module
->idx_to_lmethod
, GINT_TO_POINTER (cfg
->method_index
), ctx
->lmethod
);
7329 if (ctx
->llvm_only
&& cfg
->orig_method
->klass
->valuetype
&& !(cfg
->orig_method
->flags
& METHOD_ATTRIBUTE_STATIC
))
7330 emit_unbox_tramp (ctx
, ctx
->method_name
, ctx
->method_type
, ctx
->lmethod
, cfg
->method_index
);
7334 * mono_llvm_create_vars:
7336 * Same as mono_arch_create_vars () for LLVM.
7339 mono_llvm_create_vars (MonoCompile
*cfg
)
7341 MonoMethodSignature
*sig
;
7343 sig
= mono_method_signature (cfg
->method
);
7344 if (cfg
->gsharedvt
&& cfg
->llvm_only
) {
7345 if (mini_is_gsharedvt_variable_signature (sig
) && sig
->ret
->type
!= MONO_TYPE_VOID
) {
7346 cfg
->vret_addr
= mono_compile_create_var (cfg
, &mono_get_intptr_class ()->byval_arg
, OP_ARG
);
7347 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
7348 printf ("vret_addr = ");
7349 mono_print_ins (cfg
->vret_addr
);
7353 mono_arch_create_vars (cfg
);
7358 * mono_llvm_emit_call:
7360 * Same as mono_arch_emit_call () for LLVM.
7363 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
7366 MonoMethodSignature
*sig
;
7367 int i
, n
, stack_size
;
7372 sig
= call
->signature
;
7373 n
= sig
->param_count
+ sig
->hasthis
;
7375 call
->cinfo
= get_llvm_call_info (cfg
, sig
);
7377 if (cfg
->disable_llvm
)
7380 if (sig
->call_convention
== MONO_CALL_VARARG
) {
7381 cfg
->exception_message
= g_strdup ("varargs");
7382 cfg
->disable_llvm
= TRUE
;
7385 for (i
= 0; i
< n
; ++i
) {
7388 ainfo
= call
->cinfo
->args
+ i
;
7390 in
= call
->args
[i
];
7392 /* Simply remember the arguments */
7393 switch (ainfo
->storage
) {
7394 case LLVMArgNormal
: {
7395 MonoType
*t
= (sig
->hasthis
&& i
== 0) ? &mono_get_intptr_class ()->byval_arg
: ainfo
->type
;
7398 opcode
= mono_type_to_regmove (cfg
, t
);
7399 if (opcode
== OP_FMOVE
) {
7400 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
7401 ins
->dreg
= mono_alloc_freg (cfg
);
7402 } else if (opcode
== OP_LMOVE
) {
7403 MONO_INST_NEW (cfg
, ins
, OP_LMOVE
);
7404 ins
->dreg
= mono_alloc_lreg (cfg
);
7405 } else if (opcode
== OP_RMOVE
) {
7406 MONO_INST_NEW (cfg
, ins
, OP_RMOVE
);
7407 ins
->dreg
= mono_alloc_freg (cfg
);
7409 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
7410 ins
->dreg
= mono_alloc_ireg (cfg
);
7412 ins
->sreg1
= in
->dreg
;
7415 case LLVMArgVtypeByVal
:
7416 case LLVMArgVtypeByRef
:
7417 case LLVMArgVtypeInReg
:
7418 case LLVMArgVtypeAsScalar
:
7419 case LLVMArgAsIArgs
:
7420 case LLVMArgAsFpArgs
:
7421 case LLVMArgGsharedvtVariable
:
7422 case LLVMArgGsharedvtFixed
:
7423 case LLVMArgGsharedvtFixedVtype
:
7424 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
7425 ins
->dreg
= mono_alloc_ireg (cfg
);
7426 ins
->sreg1
= in
->dreg
;
7427 ins
->inst_p0
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMArgInfo
));
7428 memcpy (ins
->inst_p0
, ainfo
, sizeof (LLVMArgInfo
));
7429 ins
->inst_vtype
= ainfo
->type
;
7430 ins
->klass
= mono_class_from_mono_type (ainfo
->type
);
7433 cfg
->exception_message
= g_strdup ("ainfo->storage");
7434 cfg
->disable_llvm
= TRUE
;
7438 if (!cfg
->disable_llvm
) {
7439 MONO_ADD_INS (cfg
->cbb
, ins
);
7440 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
7445 static unsigned char*
7446 alloc_cb (LLVMValueRef function
, int size
)
7450 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7454 return (unsigned char*)mono_domain_code_reserve (cfg
->domain
, size
);
7456 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size
);
7461 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
7465 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7467 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
7471 exception_cb (void *data
)
7474 MonoJitExceptionInfo
*ei
;
7475 guint32 ei_len
, i
, j
, nested_len
, nindex
;
7476 gpointer
*type_info
;
7477 int this_reg
, this_offset
;
7479 cfg
= (MonoCompile
*)mono_native_tls_get_value (current_cfg_tls_id
);
7483 * data points to a DWARF FDE structure, convert it to our unwind format and
7485 * An alternative would be to save it directly, and modify our unwinder to work
7488 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
);
7489 if (cfg
->verbose_level
> 1)
7490 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7492 /* Count nested clauses */
7494 for (i
= 0; i
< ei_len
; ++i
) {
7495 gint32 cindex1
= *(gint32
*)type_info
[i
];
7496 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7498 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7500 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7502 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7508 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7509 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7510 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7511 /* Fill the rest of the information from the type info */
7512 for (i
= 0; i
< ei_len
; ++i
) {
7513 gint32 clause_index
= *(gint32
*)type_info
[i
];
7514 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7516 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7517 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7518 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7522 * For nested clauses, the LLVM produced exception info associates the try interval with
7523 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7524 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7525 * and everything else from the nested clause.
7528 for (i
= 0; i
< ei_len
; ++i
) {
7529 gint32 cindex1
= *(gint32
*)type_info
[i
];
7530 MonoExceptionClause
*clause1
= &cfg
->header
->clauses
[cindex1
];
7532 for (j
= 0; j
< cfg
->header
->num_clauses
; ++j
) {
7534 MonoExceptionClause
*clause2
= &cfg
->header
->clauses
[cindex2
];
7535 MonoJitExceptionInfo
*nesting_ei
, *nested_ei
;
7537 if (cindex1
!= cindex2
&& clause1
->try_offset
>= clause2
->try_offset
&& clause1
->handler_offset
<= clause2
->handler_offset
) {
7538 /* clause1 is the nested clause */
7539 nested_ei
= &cfg
->llvm_ex_info
[i
];
7540 nesting_ei
= &cfg
->llvm_ex_info
[nindex
];
7543 memcpy (nesting_ei
, nested_ei
, sizeof (MonoJitExceptionInfo
));
7545 nesting_ei
->flags
= clause2
->flags
;
7546 nesting_ei
->data
.catch_class
= clause2
->data
.catch_class
;
7547 nesting_ei
->clause_index
= cindex2
;
7551 g_assert (nindex
== ei_len
+ nested_len
);
7552 cfg
->llvm_this_reg
= this_reg
;
7553 cfg
->llvm_this_offset
= this_offset
;
7555 /* type_info [i] is cfg mempool allocated, no need to free it */
7561 #if LLVM_API_VERSION > 100
7563 * decode_llvm_eh_info:
7565 * Decode the EH table emitted by llvm in jit mode, and store
7566 * the result into cfg.
7569 decode_llvm_eh_info (EmitContext
*ctx
, gpointer eh_frame
)
7571 MonoCompile
*cfg
= ctx
->cfg
;
7574 MonoLLVMFDEInfo info
;
7575 MonoJitExceptionInfo
*ei
;
7576 guint8
*p
= eh_frame
;
7577 int version
, fde_count
, fde_offset
;
7578 guint32 ei_len
, i
, nested_len
;
7579 gpointer
*type_info
;
7583 * Decode the one element EH table emitted by the MonoException class
7587 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7590 g_assert (version
== 3);
7593 p
= (guint8
*)ALIGN_PTR_TO (p
, 4);
7595 fde_count
= *(guint32
*)p
;
7599 g_assert (fde_count
<= 2);
7601 /* The first entry is the real method */
7602 g_assert (table
[0] == 1);
7603 fde_offset
= table
[1];
7604 table
+= fde_count
* 2;
7606 cfg
->code_len
= table
[0];
7607 fde_len
= table
[1] - fde_offset
;
7610 fde
= (guint8
*)eh_frame
+ fde_offset
;
7611 cie
= (guint8
*)table
;
7613 mono_unwind_decode_llvm_mono_fde (fde
, fde_len
, cie
, cfg
->native_code
, &info
);
7615 cfg
->encoded_unwind_ops
= info
.unw_info
;
7616 cfg
->encoded_unwind_ops_len
= info
.unw_info_len
;
7617 if (cfg
->verbose_level
> 1)
7618 mono_print_unwind_info (cfg
->encoded_unwind_ops
, cfg
->encoded_unwind_ops_len
);
7619 if (info
.this_reg
!= -1) {
7620 cfg
->llvm_this_reg
= info
.this_reg
;
7621 cfg
->llvm_this_offset
= info
.this_offset
;
7625 ei_len
= info
.ex_info_len
;
7626 type_info
= info
.type_info
;
7628 // Nested clauses are currently disabled
7631 cfg
->llvm_ex_info
= (MonoJitExceptionInfo
*)mono_mempool_alloc0 (cfg
->mempool
, (ei_len
+ nested_len
) * sizeof (MonoJitExceptionInfo
));
7632 cfg
->llvm_ex_info_len
= ei_len
+ nested_len
;
7633 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
7634 /* Fill the rest of the information from the type info */
7635 for (i
= 0; i
< ei_len
; ++i
) {
7636 gint32 clause_index
= *(gint32
*)type_info
[i
];
7637 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
7639 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
7640 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
7641 cfg
->llvm_ex_info
[i
].clause_index
= clause_index
;
7647 dlsym_cb (const char *name
, void **symbol
)
7653 if (!strcmp (name
, "__bzero")) {
7654 *symbol
= (void*)bzero
;
7656 current
= mono_dl_open (NULL
, 0, NULL
);
7659 err
= mono_dl_symbol (current
, name
, symbol
);
7661 mono_dl_close (current
);
7663 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7664 *symbol
= (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8
*)(*symbol
));
7670 AddFunc (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef
*param_types
, int nparams
)
7672 LLVMAddFunction (module
, name
, LLVMFunctionType (ret_type
, param_types
, nparams
, FALSE
));
7676 AddFunc2 (LLVMModuleRef module
, const char *name
, LLVMTypeRef ret_type
, LLVMTypeRef param_type1
, LLVMTypeRef param_type2
)
7678 LLVMTypeRef param_types
[4];
7680 param_types
[0] = param_type1
;
7681 param_types
[1] = param_type2
;
7683 AddFunc (module
, name
, ret_type
, param_types
, 2);
7689 INTRINS_SADD_OVF_I32
,
7690 INTRINS_UADD_OVF_I32
,
7691 INTRINS_SSUB_OVF_I32
,
7692 INTRINS_USUB_OVF_I32
,
7693 INTRINS_SMUL_OVF_I32
,
7694 INTRINS_UMUL_OVF_I32
,
7695 INTRINS_SADD_OVF_I64
,
7696 INTRINS_UADD_OVF_I64
,
7697 INTRINS_SSUB_OVF_I64
,
7698 INTRINS_USUB_OVF_I64
,
7699 INTRINS_SMUL_OVF_I64
,
7700 INTRINS_UMUL_OVF_I64
,
7707 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7708 INTRINS_SSE_PMOVMSKB
,
7709 INTRINS_SSE_PSRLI_W
,
7710 INTRINS_SSE_PSRAI_W
,
7711 INTRINS_SSE_PSLLI_W
,
7712 INTRINS_SSE_PSRLI_D
,
7713 INTRINS_SSE_PSRAI_D
,
7714 INTRINS_SSE_PSLLI_D
,
7715 INTRINS_SSE_PSRLI_Q
,
7716 INTRINS_SSE_PSLLI_Q
,
7717 INTRINS_SSE_SQRT_PD
,
7718 INTRINS_SSE_SQRT_PS
,
7719 INTRINS_SSE_RSQRT_PS
,
7721 INTRINS_SSE_CVTTPD2DQ
,
7722 INTRINS_SSE_CVTTPS2DQ
,
7723 INTRINS_SSE_CVTDQ2PD
,
7724 INTRINS_SSE_CVTDQ2PS
,
7725 INTRINS_SSE_CVTPD2DQ
,
7726 INTRINS_SSE_CVTPS2DQ
,
7727 INTRINS_SSE_CVTPD2PS
,
7728 INTRINS_SSE_CVTPS2PD
,
7731 INTRINS_SSE_PACKSSWB
,
7732 INTRINS_SSE_PACKUSWB
,
7733 INTRINS_SSE_PACKSSDW
,
7734 INTRINS_SSE_PACKUSDW
,
7739 INTRINS_SSE_ADDSUBPS
,
7744 INTRINS_SSE_ADDSUBPD
,
7747 INTRINS_SSE_PADDUSW
,
7748 INTRINS_SSE_PSUBUSW
,
7754 INTRINS_SSE_PADDUSB
,
7755 INTRINS_SSE_PSUBUSB
,
7767 static IntrinsicDesc intrinsics
[] = {
7768 {INTRINS_MEMSET
, "llvm.memset.p0i8.i32"},
7769 {INTRINS_MEMCPY
, "llvm.memcpy.p0i8.p0i8.i32"},
7770 {INTRINS_SADD_OVF_I32
, "llvm.sadd.with.overflow.i32"},
7771 {INTRINS_UADD_OVF_I32
, "llvm.uadd.with.overflow.i32"},
7772 {INTRINS_SSUB_OVF_I32
, "llvm.ssub.with.overflow.i32"},
7773 {INTRINS_USUB_OVF_I32
, "llvm.usub.with.overflow.i32"},
7774 {INTRINS_SMUL_OVF_I32
, "llvm.smul.with.overflow.i32"},
7775 {INTRINS_UMUL_OVF_I32
, "llvm.umul.with.overflow.i32"},
7776 {INTRINS_SADD_OVF_I64
, "llvm.sadd.with.overflow.i64"},
7777 {INTRINS_UADD_OVF_I64
, "llvm.uadd.with.overflow.i64"},
7778 {INTRINS_SSUB_OVF_I64
, "llvm.ssub.with.overflow.i64"},
7779 {INTRINS_USUB_OVF_I64
, "llvm.usub.with.overflow.i64"},
7780 {INTRINS_SMUL_OVF_I64
, "llvm.smul.with.overflow.i64"},
7781 {INTRINS_UMUL_OVF_I64
, "llvm.umul.with.overflow.i64"},
7782 {INTRINS_SIN
, "llvm.sin.f64"},
7783 {INTRINS_COS
, "llvm.cos.f64"},
7784 {INTRINS_SQRT
, "llvm.sqrt.f64"},
7785 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7786 {INTRINS_FABS
, "fabs"},
7787 {INTRINS_EXPECT_I8
, "llvm.expect.i8"},
7788 {INTRINS_EXPECT_I1
, "llvm.expect.i1"},
7789 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7790 {INTRINS_SSE_PMOVMSKB
, "llvm.x86.sse2.pmovmskb.128"},
7791 {INTRINS_SSE_PSRLI_W
, "llvm.x86.sse2.psrli.w"},
7792 {INTRINS_SSE_PSRAI_W
, "llvm.x86.sse2.psrai.w"},
7793 {INTRINS_SSE_PSLLI_W
, "llvm.x86.sse2.pslli.w"},
7794 {INTRINS_SSE_PSRLI_D
, "llvm.x86.sse2.psrli.d"},
7795 {INTRINS_SSE_PSRAI_D
, "llvm.x86.sse2.psrai.d"},
7796 {INTRINS_SSE_PSLLI_D
, "llvm.x86.sse2.pslli.d"},
7797 {INTRINS_SSE_PSRLI_Q
, "llvm.x86.sse2.psrli.q"},
7798 {INTRINS_SSE_PSLLI_Q
, "llvm.x86.sse2.pslli.q"},
7799 {INTRINS_SSE_SQRT_PD
, "llvm.x86.sse2.sqrt.pd"},
7800 {INTRINS_SSE_SQRT_PS
, "llvm.x86.sse.sqrt.ps"},
7801 {INTRINS_SSE_RSQRT_PS
, "llvm.x86.sse.rsqrt.ps"},
7802 {INTRINS_SSE_RCP_PS
, "llvm.x86.sse.rcp.ps"},
7803 {INTRINS_SSE_CVTTPD2DQ
, "llvm.x86.sse2.cvttpd2dq"},
7804 {INTRINS_SSE_CVTTPS2DQ
, "llvm.x86.sse2.cvttps2dq"},
7805 {INTRINS_SSE_CVTDQ2PD
, "llvm.x86.sse2.cvtdq2pd"},
7806 {INTRINS_SSE_CVTDQ2PS
, "llvm.x86.sse2.cvtdq2ps"},
7807 {INTRINS_SSE_CVTPD2DQ
, "llvm.x86.sse2.cvtpd2dq"},
7808 {INTRINS_SSE_CVTPS2DQ
, "llvm.x86.sse2.cvtps2dq"},
7809 {INTRINS_SSE_CVTPD2PS
, "llvm.x86.sse2.cvtpd2ps"},
7810 {INTRINS_SSE_CVTPS2PD
, "llvm.x86.sse2.cvtps2pd"},
7811 {INTRINS_SSE_CMPPD
, "llvm.x86.sse2.cmp.pd"},
7812 {INTRINS_SSE_CMPPS
, "llvm.x86.sse.cmp.ps"},
7813 {INTRINS_SSE_PACKSSWB
, "llvm.x86.sse2.packsswb.128"},
7814 {INTRINS_SSE_PACKUSWB
, "llvm.x86.sse2.packuswb.128"},
7815 {INTRINS_SSE_PACKSSDW
, "llvm.x86.sse2.packssdw.128"},
7816 {INTRINS_SSE_PACKUSDW
, "llvm.x86.sse41.packusdw"},
7817 {INTRINS_SSE_MINPS
, "llvm.x86.sse.min.ps"},
7818 {INTRINS_SSE_MAXPS
, "llvm.x86.sse.max.ps"},
7819 {INTRINS_SSE_HADDPS
, "llvm.x86.sse3.hadd.ps"},
7820 {INTRINS_SSE_HSUBPS
, "llvm.x86.sse3.hsub.ps"},
7821 {INTRINS_SSE_ADDSUBPS
, "llvm.x86.sse3.addsub.ps"},
7822 {INTRINS_SSE_MINPD
, "llvm.x86.sse2.min.pd"},
7823 {INTRINS_SSE_MAXPD
, "llvm.x86.sse2.max.pd"},
7824 {INTRINS_SSE_HADDPD
, "llvm.x86.sse3.hadd.pd"},
7825 {INTRINS_SSE_HSUBPD
, "llvm.x86.sse3.hsub.pd"},
7826 {INTRINS_SSE_ADDSUBPD
, "llvm.x86.sse3.addsub.pd"},
7827 {INTRINS_SSE_PADDSW
, "llvm.x86.sse2.padds.w"},
7828 {INTRINS_SSE_PSUBSW
, "llvm.x86.sse2.psubs.w"},
7829 {INTRINS_SSE_PADDUSW
, "llvm.x86.sse2.paddus.w"},
7830 {INTRINS_SSE_PSUBUSW
, "llvm.x86.sse2.psubus.w"},
7831 {INTRINS_SSE_PAVGW
, "llvm.x86.sse2.pavg.w"},
7832 {INTRINS_SSE_PMULHW
, "llvm.x86.sse2.pmulh.w"},
7833 {INTRINS_SSE_PMULHU
, "llvm.x86.sse2.pmulhu.w"},
7834 {INTRINS_SE_PADDSB
, "llvm.x86.sse2.padds.b"},
7835 {INTRINS_SSE_PSUBSB
, "llvm.x86.sse2.psubs.b"},
7836 {INTRINS_SSE_PADDUSB
, "llvm.x86.sse2.paddus.b"},
7837 {INTRINS_SSE_PSUBUSB
, "llvm.x86.sse2.psubus.b"},
7838 {INTRINS_SSE_PAVGB
, "llvm.x86.sse2.pavg.b"},
7839 {INTRINS_SSE_PAUSE
, "llvm.x86.sse2.pause"}
7844 add_sse_binary (LLVMModuleRef module
, const char *name
, int type
)
7846 LLVMTypeRef ret_type
= type_to_simd_type (type
);
7847 AddFunc2 (module
, name
, ret_type
, ret_type
, ret_type
);
7851 add_intrinsic (LLVMModuleRef module
, int id
)
7854 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7855 LLVMTypeRef ret_type
, arg_types
[16];
7858 name
= g_hash_table_lookup (intrins_id_to_name
, GINT_TO_POINTER (id
));
7862 case INTRINS_MEMSET
: {
7863 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7865 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
7868 case INTRINS_MEMCPY
: {
7869 LLVMTypeRef params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7871 AddFunc (module
, name
, LLVMVoidType (), params
, 5);
7874 case INTRINS_SADD_OVF_I32
:
7875 case INTRINS_UADD_OVF_I32
:
7876 case INTRINS_SSUB_OVF_I32
:
7877 case INTRINS_USUB_OVF_I32
:
7878 case INTRINS_SMUL_OVF_I32
:
7879 case INTRINS_UMUL_OVF_I32
: {
7880 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
7881 LLVMTypeRef params
[] = { LLVMInt32Type (), LLVMInt32Type () };
7882 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i32
, 2, FALSE
);
7884 AddFunc (module
, name
, ret_type
, params
, 2);
7887 case INTRINS_SADD_OVF_I64
:
7888 case INTRINS_UADD_OVF_I64
:
7889 case INTRINS_SSUB_OVF_I64
:
7890 case INTRINS_USUB_OVF_I64
:
7891 case INTRINS_SMUL_OVF_I64
:
7892 case INTRINS_UMUL_OVF_I64
: {
7893 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
7894 LLVMTypeRef params
[] = { LLVMInt64Type (), LLVMInt64Type () };
7895 LLVMTypeRef ret_type
= LLVMStructType (ovf_res_i64
, 2, FALSE
);
7897 AddFunc (module
, name
, ret_type
, params
, 2);
7903 case INTRINS_FABS
: {
7904 LLVMTypeRef params
[] = { LLVMDoubleType () };
7906 AddFunc (module
, name
, LLVMDoubleType (), params
, 1);
7909 case INTRINS_EXPECT_I8
:
7910 AddFunc2 (module
, name
, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7912 case INTRINS_EXPECT_I1
:
7913 AddFunc2 (module
, name
, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7915 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7916 case INTRINS_SSE_PMOVMSKB
:
7918 ret_type
= LLVMInt32Type ();
7919 arg_types
[0] = type_to_simd_type (MONO_TYPE_I1
);
7920 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7922 case INTRINS_SSE_PSRLI_W
:
7923 case INTRINS_SSE_PSRAI_W
:
7924 case INTRINS_SSE_PSLLI_W
:
7926 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
7927 arg_types
[0] = ret_type
;
7928 arg_types
[1] = LLVMInt32Type ();
7929 AddFunc (module
, name
, ret_type
, arg_types
, 2);
7931 case INTRINS_SSE_PSRLI_D
:
7932 case INTRINS_SSE_PSRAI_D
:
7933 case INTRINS_SSE_PSLLI_D
:
7934 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
7935 arg_types
[0] = ret_type
;
7936 arg_types
[1] = LLVMInt32Type ();
7937 AddFunc (module
, name
, ret_type
, arg_types
, 2);
7939 case INTRINS_SSE_PSRLI_Q
:
7940 case INTRINS_SSE_PSLLI_Q
:
7941 ret_type
= type_to_simd_type (MONO_TYPE_I8
);
7942 arg_types
[0] = ret_type
;
7943 arg_types
[1] = LLVMInt32Type ();
7944 AddFunc (module
, name
, ret_type
, arg_types
, 2);
7946 case INTRINS_SSE_SQRT_PD
:
7948 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
7949 arg_types
[0] = ret_type
;
7950 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7952 case INTRINS_SSE_SQRT_PS
:
7953 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
7954 arg_types
[0] = ret_type
;
7955 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7957 case INTRINS_SSE_RSQRT_PS
:
7958 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
7959 arg_types
[0] = ret_type
;
7960 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7962 case INTRINS_SSE_RCP_PS
:
7963 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
7964 arg_types
[0] = ret_type
;
7965 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7967 case INTRINS_SSE_CVTTPD2DQ
:
7968 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
7969 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
7970 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7972 case INTRINS_SSE_CVTTPS2DQ
:
7973 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
7974 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
7975 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7977 case INTRINS_SSE_CVTDQ2PD
:
7978 /* Conversion ops */
7979 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
7980 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
7981 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7983 case INTRINS_SSE_CVTDQ2PS
:
7984 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
7985 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
7986 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7988 case INTRINS_SSE_CVTPD2DQ
:
7989 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
7990 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
7991 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7993 case INTRINS_SSE_CVTPS2DQ
:
7994 ret_type
= type_to_simd_type (MONO_TYPE_I4
);
7995 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
7996 AddFunc (module
, name
, ret_type
, arg_types
, 1);
7998 case INTRINS_SSE_CVTPD2PS
:
7999 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8000 arg_types
[0] = type_to_simd_type (MONO_TYPE_R8
);
8001 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8003 case INTRINS_SSE_CVTPS2PD
:
8004 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8005 arg_types
[0] = type_to_simd_type (MONO_TYPE_R4
);
8006 AddFunc (module
, name
, ret_type
, arg_types
, 1);
8008 case INTRINS_SSE_CMPPD
:
8010 ret_type
= type_to_simd_type (MONO_TYPE_R8
);
8011 arg_types
[0] = ret_type
;
8012 arg_types
[1] = ret_type
;
8013 arg_types
[2] = LLVMInt8Type ();
8014 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8016 case INTRINS_SSE_CMPPS
:
8017 ret_type
= type_to_simd_type (MONO_TYPE_R4
);
8018 arg_types
[0] = ret_type
;
8019 arg_types
[1] = ret_type
;
8020 arg_types
[2] = LLVMInt8Type ();
8021 AddFunc (module
, name
, ret_type
, arg_types
, 3);
8023 case INTRINS_SSE_PACKSSWB
:
8024 case INTRINS_SSE_PACKUSWB
:
8025 case INTRINS_SSE_PACKSSDW
:
8027 ret_type
= type_to_simd_type (MONO_TYPE_I1
);
8028 arg_types
[0] = type_to_simd_type (MONO_TYPE_I2
);
8029 arg_types
[1] = type_to_simd_type (MONO_TYPE_I2
);
8030 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8032 case INTRINS_SSE_PACKUSDW
:
8033 ret_type
= type_to_simd_type (MONO_TYPE_I2
);
8034 arg_types
[0] = type_to_simd_type (MONO_TYPE_I4
);
8035 arg_types
[1] = type_to_simd_type (MONO_TYPE_I4
);
8036 AddFunc (module
, name
, ret_type
, arg_types
, 2);
8038 /* SSE Binary ops */
8039 case INTRINS_SSE_PADDSW
:
8040 case INTRINS_SSE_PSUBSW
:
8041 case INTRINS_SSE_PADDUSW
:
8042 case INTRINS_SSE_PSUBUSW
:
8043 case INTRINS_SSE_PAVGW
:
8044 case INTRINS_SSE_PMULHW
:
8045 case INTRINS_SSE_PMULHU
:
8046 add_sse_binary (module
, name
, MONO_TYPE_I2
);
8048 case INTRINS_SSE_MINPS
:
8049 case INTRINS_SSE_MAXPS
:
8050 case INTRINS_SSE_HADDPS
:
8051 case INTRINS_SSE_HSUBPS
:
8052 case INTRINS_SSE_ADDSUBPS
:
8053 add_sse_binary (module
, name
, MONO_TYPE_R4
);
8055 case INTRINS_SSE_MINPD
:
8056 case INTRINS_SSE_MAXPD
:
8057 case INTRINS_SSE_HADDPD
:
8058 case INTRINS_SSE_HSUBPD
:
8059 case INTRINS_SSE_ADDSUBPD
:
8060 add_sse_binary (module
, name
, MONO_TYPE_R8
);
8062 case INTRINS_SE_PADDSB
:
8063 case INTRINS_SSE_PSUBSB
:
8064 case INTRINS_SSE_PADDUSB
:
8065 case INTRINS_SSE_PSUBUSB
:
8066 case INTRINS_SSE_PAVGB
:
8067 add_sse_binary (module
, name
, MONO_TYPE_I1
);
8069 case INTRINS_SSE_PAUSE
:
8070 AddFunc (module
, "llvm.x86.sse2.pause", LLVMVoidType (), NULL
, 0);
8074 g_assert_not_reached ();
8080 get_intrinsic (EmitContext
*ctx
, const char *name
)
8082 #if LLVM_API_VERSION > 100
8086 * Every method is emitted into its own module so
8087 * we can add intrinsics on demand.
8089 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8093 /* No locking needed */
8094 id
= GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id
, name
));
8097 printf ("%s\n", name
);
8098 g_assert (id
!= -1);
8099 add_intrinsic (ctx
->lmodule
, id
);
8100 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8108 res
= LLVMGetNamedFunction (ctx
->lmodule
, name
);
8115 add_intrinsics (LLVMModuleRef module
)
8119 /* Emit declarations of instrinsics */
8121 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8122 * type doesn't seem to do any locking.
8124 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8125 add_intrinsic (module
, i
);
8129 AddFunc (module
, "mono_personality", LLVMVoidType (), NULL
, 0);
8131 AddFunc (module
, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL
, 0);
8134 /* Load/Store intrinsics */
8136 LLVMTypeRef arg_types
[5];
8140 for (i
= 1; i
<= 8; i
*= 2) {
8141 arg_types
[0] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8142 arg_types
[1] = LLVMInt32Type ();
8143 arg_types
[2] = LLVMInt1Type ();
8144 arg_types
[3] = LLVMInt32Type ();
8145 sprintf (name
, "llvm.mono.load.i%d.p0i%d", i
* 8, i
* 8);
8146 AddFunc (module
, name
, LLVMIntType (i
* 8), arg_types
, 4);
8148 arg_types
[0] = LLVMIntType (i
* 8);
8149 arg_types
[1] = LLVMPointerType (LLVMIntType (i
* 8), 0);
8150 arg_types
[2] = LLVMInt32Type ();
8151 arg_types
[3] = LLVMInt1Type ();
8152 arg_types
[4] = LLVMInt32Type ();
8153 sprintf (name
, "llvm.mono.store.i%d.p0i%d", i
* 8, i
* 8);
8154 AddFunc (module
, name
, LLVMVoidType (), arg_types
, 5);
8160 add_types (MonoLLVMModule
*module
)
8162 module
->ptr_type
= LLVMPointerType (sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8166 mono_llvm_init (void)
8171 mono_native_tls_alloc (¤t_cfg_tls_id
, NULL
);
8173 h
= g_hash_table_new (NULL
, NULL
);
8174 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8175 g_hash_table_insert (h
, GINT_TO_POINTER (intrinsics
[i
].id
), (gpointer
)intrinsics
[i
].name
);
8176 intrins_id_to_name
= h
;
8178 h
= g_hash_table_new (g_str_hash
, g_str_equal
);
8179 for (i
= 0; i
< INTRINS_NUM
; ++i
)
8180 g_hash_table_insert (h
, (gpointer
)intrinsics
[i
].name
, GINT_TO_POINTER (intrinsics
[i
].id
+ 1));
8181 intrins_name_to_id
= h
;
8185 init_jit_module (MonoDomain
*domain
)
8187 MonoJitDomainInfo
*dinfo
;
8188 MonoLLVMModule
*module
;
8191 dinfo
= domain_jit_info (domain
);
8192 if (dinfo
->llvm_module
)
8195 mono_loader_lock ();
8197 if (dinfo
->llvm_module
) {
8198 mono_loader_unlock ();
8202 module
= g_new0 (MonoLLVMModule
, 1);
8204 name
= g_strdup_printf ("mono-%s", domain
->friendly_name
);
8205 module
->lmodule
= LLVMModuleCreateWithName (name
);
8206 module
->context
= LLVMGetGlobalContext ();
8208 module
->mono_ee
= (MonoEERef
*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module
->lmodule
), alloc_cb
, emitted_cb
, exception_cb
, dlsym_cb
, &module
->ee
);
8210 add_intrinsics (module
->lmodule
);
8213 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8215 #if LLVM_API_VERSION < 100
8216 MonoJitICallInfo
*info
;
8218 info
= mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8220 LLVMAddGlobalMapping (module
->ee
, LLVMGetNamedFunction (module
->lmodule
, "llvm_resume_unwind_trampoline"), (void*)info
->func
);
8223 mono_memory_barrier ();
8225 dinfo
->llvm_module
= module
;
8227 mono_loader_unlock ();
8231 mono_llvm_cleanup (void)
8233 MonoLLVMModule
*module
= &aot_module
;
8235 if (module
->lmodule
)
8236 LLVMDisposeModule (module
->lmodule
);
8238 if (module
->context
)
8239 LLVMContextDispose (module
->context
);
8243 mono_llvm_free_domain_info (MonoDomain
*domain
)
8245 MonoJitDomainInfo
*info
= domain_jit_info (domain
);
8246 MonoLLVMModule
*module
= (MonoLLVMModule
*)info
->llvm_module
;
8252 if (module
->llvm_types
)
8253 g_hash_table_destroy (module
->llvm_types
);
8255 mono_llvm_dispose_ee (module
->mono_ee
);
8257 if (module
->bb_names
) {
8258 for (i
= 0; i
< module
->bb_names_len
; ++i
)
8259 g_free (module
->bb_names
[i
]);
8260 g_free (module
->bb_names
);
8262 //LLVMDisposeModule (module->module);
8266 info
->llvm_module
= NULL
;
8270 mono_llvm_create_aot_module (MonoAssembly
*assembly
, const char *global_prefix
, gboolean emit_dwarf
, gboolean static_link
, gboolean llvm_only
)
8272 MonoLLVMModule
*module
= &aot_module
;
8274 /* Delete previous module */
8275 if (module
->plt_entries
)
8276 g_hash_table_destroy (module
->plt_entries
);
8277 if (module
->lmodule
)
8278 LLVMDisposeModule (module
->lmodule
);
8280 memset (module
, 0, sizeof (aot_module
));
8282 module
->lmodule
= LLVMModuleCreateWithName ("aot");
8283 module
->assembly
= assembly
;
8284 module
->global_prefix
= g_strdup (global_prefix
);
8285 module
->got_symbol
= g_strdup_printf ("%s_llvm_got", global_prefix
);
8286 module
->eh_frame_symbol
= g_strdup_printf ("%s_eh_frame", global_prefix
);
8287 module
->get_method_symbol
= g_strdup_printf ("%s_get_method", global_prefix
);
8288 module
->get_unbox_tramp_symbol
= g_strdup_printf ("%s_get_unbox_tramp", global_prefix
);
8289 module
->external_symbols
= TRUE
;
8290 module
->emit_dwarf
= emit_dwarf
;
8291 module
->static_link
= static_link
;
8292 module
->llvm_only
= llvm_only
;
8293 /* The first few entries are reserved */
8294 module
->max_got_offset
= 16;
8295 module
->context
= LLVMContextCreate ();
8298 /* clang ignores our debug info because it has an invalid version */
8299 module
->emit_dwarf
= FALSE
;
8301 #if LLVM_API_VERSION > 100
8302 module
->emit_dwarf
= FALSE
;
8305 add_intrinsics (module
->lmodule
);
8308 #if LLVM_API_VERSION > 100
8309 if (module
->emit_dwarf
) {
8310 char *dir
, *build_info
, *s
, *cu_name
;
8312 module
->di_builder
= mono_llvm_create_di_builder (module
->lmodule
);
8315 dir
= g_strdup (".");
8316 build_info
= mono_get_runtime_build_info ();
8317 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8318 cu_name
= g_path_get_basename (assembly
->image
->name
);
8319 module
->cu
= mono_llvm_di_create_compile_unit (module
->di_builder
, cu_name
, dir
, s
);
8321 g_free (build_info
);
8328 * We couldn't compute the type of the LLVM global representing the got because
8329 * its size is only known after all the methods have been emitted. So create
8330 * a dummy variable, and replace all uses it with the real got variable when
8331 * its size is known in mono_llvm_emit_aot_module ().
8334 LLVMTypeRef got_type
= LLVMArrayType (module
->ptr_type
, 0);
8336 module
->got_var
= LLVMAddGlobal (module
->lmodule
, got_type
, "mono_dummy_got");
8337 LLVMSetInitializer (module
->got_var
, LLVMConstNull (got_type
));
8340 /* Add initialization array */
8342 LLVMTypeRef inited_type
= LLVMArrayType (LLVMInt8Type (), 0);
8344 module
->inited_var
= LLVMAddGlobal (aot_module
.lmodule
, inited_type
, "mono_inited_tmp");
8345 LLVMSetInitializer (module
->inited_var
, LLVMConstNull (inited_type
));
8349 emit_init_icall_wrappers (module
);
8351 emit_llvm_code_start (module
);
8353 /* Add a dummy personality function */
8354 if (!use_debug_personality
) {
8355 LLVMValueRef personality
= LLVMAddFunction (module
->lmodule
, default_personality_name
, LLVMFunctionType (LLVMInt32Type (), NULL
, 0, TRUE
));
8356 LLVMSetLinkage (personality
, LLVMExternalLinkage
);
8357 mark_as_used (module
, personality
);
8360 /* Add a reference to the c++ exception we throw/catch */
8362 LLVMTypeRef exc
= LLVMPointerType (LLVMInt8Type (), 0);
8363 module
->sentinel_exception
= LLVMAddGlobal (module
->lmodule
, exc
, "_ZTIPi");
8364 LLVMSetLinkage (module
->sentinel_exception
, LLVMExternalLinkage
);
8365 mono_llvm_set_is_constant (module
->sentinel_exception
);
8368 module
->llvm_types
= g_hash_table_new (NULL
, NULL
);
8369 module
->plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
8370 module
->plt_entries_ji
= g_hash_table_new (NULL
, NULL
);
8371 module
->direct_callables
= g_hash_table_new (g_str_hash
, g_str_equal
);
8372 module
->method_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8373 module
->idx_to_lmethod
= g_hash_table_new (NULL
, NULL
);
8374 module
->idx_to_unbox_tramp
= g_hash_table_new (NULL
, NULL
);
8375 module
->method_to_callers
= g_hash_table_new (NULL
, NULL
);
8379 llvm_array_from_uints (LLVMTypeRef el_type
, guint32
*values
, int nvalues
)
8382 LLVMValueRef res
, *vals
;
8384 vals
= g_new0 (LLVMValueRef
, nvalues
);
8385 for (i
= 0; i
< nvalues
; ++i
)
8386 vals
[i
] = LLVMConstInt (LLVMInt32Type (), values
[i
], FALSE
);
8387 res
= LLVMConstArray (LLVMInt32Type (), vals
, nvalues
);
8393 llvm_array_from_bytes (guint8
*values
, int nvalues
)
8396 LLVMValueRef res
, *vals
;
8398 vals
= g_new0 (LLVMValueRef
, nvalues
);
8399 for (i
= 0; i
< nvalues
; ++i
)
8400 vals
[i
] = LLVMConstInt (LLVMInt8Type (), values
[i
], FALSE
);
8401 res
= LLVMConstArray (LLVMInt8Type (), vals
, nvalues
);
8406 * mono_llvm_emit_aot_file_info:
8408 * Emit the MonoAotFileInfo structure.
8409 * Same as emit_aot_file_info () in aot-compiler.c.
8412 mono_llvm_emit_aot_file_info (MonoAotFileInfo
*info
, gboolean has_jitted_code
)
8414 MonoLLVMModule
*module
= &aot_module
;
8416 /* Save these for later */
8417 memcpy (&module
->aot_info
, info
, sizeof (MonoAotFileInfo
));
8418 module
->has_jitted_code
= has_jitted_code
;
8422 * mono_llvm_emit_aot_data:
8424 * Emit the binary data DATA pointed to by symbol SYMBOL.
8427 mono_llvm_emit_aot_data (const char *symbol
, guint8
*data
, int data_len
)
8429 MonoLLVMModule
*module
= &aot_module
;
8433 type
= LLVMArrayType (LLVMInt8Type (), data_len
);
8434 d
= LLVMAddGlobal (module
->lmodule
, type
, symbol
);
8435 LLVMSetVisibility (d
, LLVMHiddenVisibility
);
8436 LLVMSetLinkage (d
, LLVMInternalLinkage
);
8437 LLVMSetInitializer (d
, mono_llvm_create_constant_data_array (data
, data_len
));
8438 mono_llvm_set_is_constant (d
);
8441 /* Add a reference to a global defined in JITted code */
8443 AddJitGlobal (MonoLLVMModule
*module
, LLVMTypeRef type
, const char *name
)
8448 s
= g_strdup_printf ("%s%s", module
->global_prefix
, name
);
8449 v
= LLVMAddGlobal (module
->lmodule
, LLVMInt8Type (), s
);
8455 emit_aot_file_info (MonoLLVMModule
*module
)
8457 LLVMTypeRef file_info_type
;
8458 LLVMTypeRef
*eltypes
, eltype
;
8459 LLVMValueRef info_var
;
8460 LLVMValueRef
*fields
;
8461 int i
, nfields
, tindex
;
8462 MonoAotFileInfo
*info
;
8463 LLVMModuleRef lmodule
= module
->lmodule
;
8465 info
= &module
->aot_info
;
8467 /* Create an LLVM type to represent MonoAotFileInfo */
8468 nfields
= 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS
+ 16 + 5;
8469 eltypes
= g_new (LLVMTypeRef
, nfields
);
8471 eltypes
[tindex
++] = LLVMInt32Type ();
8472 eltypes
[tindex
++] = LLVMInt32Type ();
8474 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8475 eltypes
[tindex
++] = LLVMPointerType (LLVMInt8Type (), 0);
8477 for (i
= 0; i
< 15; ++i
)
8478 eltypes
[tindex
++] = LLVMInt32Type ();
8480 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM
);
8481 for (i
= 0; i
< 4; ++i
)
8482 eltypes
[tindex
++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM
);
8483 eltypes
[tindex
++] = LLVMArrayType (LLVMInt8Type (), 16);
8484 g_assert (tindex
== nfields
);
8485 file_info_type
= LLVMStructCreateNamed (module
->context
, "MonoAotFileInfo");
8486 LLVMStructSetBody (file_info_type
, eltypes
, nfields
, FALSE
);
8488 info_var
= LLVMAddGlobal (lmodule
, file_info_type
, "mono_aot_file_info");
8489 if (module
->static_link
) {
8490 LLVMSetVisibility (info_var
, LLVMHiddenVisibility
);
8491 LLVMSetLinkage (info_var
, LLVMInternalLinkage
);
8493 fields
= g_new (LLVMValueRef
, nfields
);
8495 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->version
, FALSE
);
8496 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->dummy
, FALSE
);
8500 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8501 * for symbols defined in the .s file emitted by the aot compiler.
8503 eltype
= eltypes
[tindex
];
8504 if (module
->llvm_only
)
8505 fields
[tindex
++] = LLVMConstNull (eltype
);
8507 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_got");
8508 fields
[tindex
++] = module
->got_var
;
8509 /* llc defines this directly */
8510 if (!module
->llvm_only
) {
8511 fields
[tindex
++] = LLVMAddGlobal (lmodule
, eltype
, module
->eh_frame_symbol
);
8512 fields
[tindex
++] = LLVMConstNull (eltype
);
8513 fields
[tindex
++] = LLVMConstNull (eltype
);
8515 fields
[tindex
++] = LLVMConstNull (eltype
);
8516 fields
[tindex
++] = module
->get_method
;
8517 fields
[tindex
++] = module
->get_unbox_tramp
;
8519 if (module
->has_jitted_code
) {
8520 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_start");
8521 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "jit_code_end");
8523 fields
[tindex
++] = LLVMConstNull (eltype
);
8524 fields
[tindex
++] = LLVMConstNull (eltype
);
8526 if (!module
->llvm_only
)
8527 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "method_addresses");
8529 fields
[tindex
++] = LLVMConstNull (eltype
);
8530 if (info
->flags
& MONO_AOT_FILE_FLAG_SEPARATE_DATA
) {
8531 for (i
= 0; i
< MONO_AOT_TABLE_NUM
; ++i
)
8532 fields
[tindex
++] = LLVMConstNull (eltype
);
8534 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "blob");
8535 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_name_table");
8536 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "class_info_offsets");
8537 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "method_info_offsets");
8538 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "ex_info_offsets");
8539 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_info_offsets");
8540 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "extra_method_table");
8541 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "got_info_offsets");
8542 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "llvm_got_info_offsets");
8543 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "image_table");
8545 /* Not needed (mem_end) */
8546 fields
[tindex
++] = LLVMConstNull (eltype
);
8547 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_guid");
8548 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "runtime_version");
8549 if (info
->trampoline_size
[0]) {
8550 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "specific_trampolines");
8551 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "static_rgctx_trampolines");
8552 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "imt_thunks");
8553 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "gsharedvt_arg_trampolines");
8555 fields
[tindex
++] = LLVMConstNull (eltype
);
8556 fields
[tindex
++] = LLVMConstNull (eltype
);
8557 fields
[tindex
++] = LLVMConstNull (eltype
);
8558 fields
[tindex
++] = LLVMConstNull (eltype
);
8560 if (module
->static_link
&& !module
->llvm_only
)
8561 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "globals");
8563 fields
[tindex
++] = LLVMConstNull (eltype
);
8564 fields
[tindex
++] = LLVMGetNamedGlobal (lmodule
, "assembly_name");
8565 if (!module
->llvm_only
) {
8566 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt");
8567 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "plt_end");
8568 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unwind_info");
8569 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines");
8570 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampolines_end");
8571 fields
[tindex
++] = AddJitGlobal (module
, eltype
, "unbox_trampoline_addresses");
8573 fields
[tindex
++] = LLVMConstNull (eltype
);
8574 fields
[tindex
++] = LLVMConstNull (eltype
);
8575 fields
[tindex
++] = LLVMConstNull (eltype
);
8576 fields
[tindex
++] = LLVMConstNull (eltype
);
8577 fields
[tindex
++] = LLVMConstNull (eltype
);
8578 fields
[tindex
++] = LLVMConstNull (eltype
);
8581 for (i
= 0; i
< MONO_AOT_FILE_INFO_NUM_SYMBOLS
; ++i
)
8582 fields
[2 + i
] = LLVMConstBitCast (fields
[2 + i
], eltype
);
8585 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_got_offset_base
, FALSE
);
8586 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->got_size
, FALSE
);
8587 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->plt_size
, FALSE
);
8588 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nmethods
, FALSE
);
8589 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->flags
, FALSE
);
8590 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->opts
, FALSE
);
8591 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->simd_opts
, FALSE
);
8592 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->gc_name_index
, FALSE
);
8593 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->num_rgctx_fetch_trampolines
, FALSE
);
8594 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->double_align
, FALSE
);
8595 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->long_align
, FALSE
);
8596 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->generic_tramp_num
, FALSE
);
8597 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->tramp_page_size
, FALSE
);
8598 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->nshared_got_entries
, FALSE
);
8599 fields
[tindex
++] = LLVMConstInt (LLVMInt32Type (), info
->datafile_size
, FALSE
);
8601 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->table_offsets
, MONO_AOT_TABLE_NUM
);
8602 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->num_trampolines
, MONO_AOT_TRAMP_NUM
);
8603 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_got_offset_base
, MONO_AOT_TRAMP_NUM
);
8604 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->trampoline_size
, MONO_AOT_TRAMP_NUM
);
8605 fields
[tindex
++] = llvm_array_from_uints (LLVMInt32Type (), info
->tramp_page_code_offsets
, MONO_AOT_TRAMP_NUM
);
8607 fields
[tindex
++] = llvm_array_from_bytes (info
->aotid
, 16);
8608 g_assert (tindex
== nfields
);
8610 LLVMSetInitializer (info_var
, LLVMConstNamedStruct (file_info_type
, fields
, nfields
));
8612 if (module
->static_link
) {
8616 s
= g_strdup_printf ("mono_aot_module_%s_info", module
->assembly
->aname
.name
);
8617 /* Get rid of characters which cannot occur in symbols */
8619 for (p
= s
; *p
; ++p
) {
8620 if (!(isalnum (*p
) || *p
== '_'))
8623 var
= LLVMAddGlobal (module
->lmodule
, LLVMPointerType (LLVMInt8Type (), 0), s
);
8625 LLVMSetInitializer (var
, LLVMConstBitCast (LLVMGetNamedGlobal (module
->lmodule
, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8626 LLVMSetLinkage (var
, LLVMExternalLinkage
);
8631 * Emit the aot module into the LLVM bitcode file FILENAME.
8634 mono_llvm_emit_aot_module (const char *filename
, const char *cu_name
)
8636 LLVMTypeRef got_type
, inited_type
;
8637 LLVMValueRef real_got
, real_inited
;
8638 MonoLLVMModule
*module
= &aot_module
;
8640 emit_llvm_code_end (module
);
8643 * Create the real got variable and replace all uses of the dummy variable with
8646 got_type
= LLVMArrayType (module
->ptr_type
, module
->max_got_offset
+ 1);
8647 real_got
= LLVMAddGlobal (module
->lmodule
, got_type
, module
->got_symbol
);
8648 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
8649 if (module
->external_symbols
) {
8650 LLVMSetLinkage (real_got
, LLVMExternalLinkage
);
8651 LLVMSetVisibility (real_got
, LLVMHiddenVisibility
);
8653 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
8655 mono_llvm_replace_uses_of (module
->got_var
, real_got
);
8657 mark_as_used (&aot_module
, real_got
);
8659 /* Delete the dummy got so it doesn't become a global */
8660 LLVMDeleteGlobal (module
->got_var
);
8661 module
->got_var
= real_got
;
8664 * Same for the init_var
8666 if (module
->llvm_only
) {
8667 inited_type
= LLVMArrayType (LLVMInt8Type (), module
->max_inited_idx
+ 1);
8668 real_inited
= LLVMAddGlobal (module
->lmodule
, inited_type
, "mono_inited");
8669 LLVMSetInitializer (real_inited
, LLVMConstNull (inited_type
));
8670 LLVMSetLinkage (real_inited
, LLVMInternalLinkage
);
8671 mono_llvm_replace_uses_of (module
->inited_var
, real_inited
);
8672 LLVMDeleteGlobal (module
->inited_var
);
8675 if (module
->llvm_only
) {
8676 emit_get_method (&aot_module
);
8677 emit_get_unbox_tramp (&aot_module
);
8680 emit_llvm_used (&aot_module
);
8681 emit_dbg_info (&aot_module
, filename
, cu_name
);
8682 emit_aot_file_info (&aot_module
);
8685 * Replace GOT entries for directly callable methods with the methods themselves.
8686 * It would be easier to implement this by predefining all methods before compiling
8687 * their bodies, but that couldn't handle the case when a method fails to compile
8690 if (module
->llvm_only
) {
8691 GHashTableIter iter
;
8693 GSList
*callers
, *l
;
8695 g_hash_table_iter_init (&iter
, module
->method_to_callers
);
8696 while (g_hash_table_iter_next (&iter
, (void**)&method
, (void**)&callers
)) {
8697 LLVMValueRef lmethod
;
8699 if (method
->iflags
& METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED
)
8702 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, method
);
8704 for (l
= callers
; l
; l
= l
->next
) {
8705 LLVMValueRef caller
= (LLVMValueRef
)l
->data
;
8707 mono_llvm_replace_uses_of (caller
, lmethod
);
8713 /* Replace PLT entries for directly callable methods with the methods themselves */
8715 GHashTableIter iter
;
8717 LLVMValueRef callee
;
8719 g_hash_table_iter_init (&iter
, module
->plt_entries_ji
);
8720 while (g_hash_table_iter_next (&iter
, (void**)&ji
, (void**)&callee
)) {
8721 if (mono_aot_is_direct_callable (ji
)) {
8722 LLVMValueRef lmethod
;
8724 lmethod
= (LLVMValueRef
)g_hash_table_lookup (module
->method_to_lmethod
, ji
->data
.method
);
8725 /* The types might not match because the caller might pass an rgctx */
8726 if (lmethod
&& LLVMTypeOf (callee
) == LLVMTypeOf (lmethod
)) {
8727 mono_llvm_replace_uses_of (callee
, lmethod
);
8728 mono_aot_mark_unused_llvm_plt_entry (ji
);
8738 if (LLVMVerifyModule (module
->lmodule
, LLVMReturnStatusAction
, &verifier_err
)) {
8739 printf ("%s\n", verifier_err
);
8740 g_assert_not_reached ();
8745 LLVMWriteBitcodeToFile (module
->lmodule
, filename
);
8750 md_string (const char *s
)
8752 return LLVMMDString (s
, strlen (s
));
8755 /* Debugging support */
8758 emit_dbg_info (MonoLLVMModule
*module
, const char *filename
, const char *cu_name
)
8760 LLVMModuleRef lmodule
= module
->lmodule
;
8761 LLVMValueRef args
[16], ver
;
8764 * This can only be enabled when LLVM code is emitted into a separate object
8765 * file, since the AOT compiler also emits dwarf info,
8766 * and the abbrev indexes will not be correct since llvm has added its own
8769 if (!module
->emit_dwarf
)
8772 #if LLVM_API_VERSION > 100
8773 mono_llvm_di_builder_finalize (module
->di_builder
);
8775 LLVMValueRef cu_args
[16], cu
;
8777 char *build_info
, *s
, *dir
;
8780 * Emit dwarf info in the form of LLVM metadata. There is some
8781 * out-of-date documentation at:
8782 * http://llvm.org/docs/SourceLevelDebugging.html
8783 * but most of this was gathered from the llvm and
8788 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit
, FALSE
);
8789 /* CU name/compilation dir */
8790 dir
= g_path_get_dirname (filename
);
8791 args
[0] = LLVMMDString (cu_name
, strlen (cu_name
));
8792 args
[1] = LLVMMDString (dir
, strlen (dir
));
8793 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 2);
8796 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99
, FALSE
);
8798 build_info
= mono_get_runtime_build_info ();
8799 s
= g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info
);
8800 cu_args
[n_cuargs
++] = LLVMMDString (s
, strlen (s
));
8801 g_free (build_info
);
8803 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8805 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8806 /* Runtime version */
8807 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8809 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8810 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8812 if (module
->subprogram_mds
) {
8816 mds
= g_new0 (LLVMValueRef
, module
->subprogram_mds
->len
);
8817 for (i
= 0; i
< module
->subprogram_mds
->len
; ++i
)
8818 mds
[i
] = (LLVMValueRef
)g_ptr_array_index (module
->subprogram_mds
, i
);
8819 cu_args
[n_cuargs
++] = LLVMMDNode (mds
, module
->subprogram_mds
->len
);
8821 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8824 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8825 /* Imported modules */
8826 cu_args
[n_cuargs
++] = LLVMMDNode (args
, 0);
8828 cu_args
[n_cuargs
++] = LLVMMDString ("", strlen (""));
8829 /* DebugEmissionKind = FullDebug */
8830 cu_args
[n_cuargs
++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8831 cu
= LLVMMDNode (cu_args
, n_cuargs
);
8832 LLVMAddNamedMetadataOperand (lmodule
, "llvm.dbg.cu", cu
);
8835 #if LLVM_API_VERSION > 100
8836 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8837 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8838 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8839 ver
= LLVMMDNode (args
, 3);
8840 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8842 args
[0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8843 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8844 args
[2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE
);
8845 ver
= LLVMMDNode (args
, 3);
8846 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8848 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8849 args
[1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8850 args
[2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE
);
8851 ver
= LLVMMDNode (args
, 3);
8852 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8854 args
[0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8855 args
[1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8856 args
[2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8857 ver
= LLVMMDNode (args
, 3);
8858 LLVMAddNamedMetadataOperand (lmodule
, "llvm.module.flags", ver
);
8863 emit_dbg_subprogram (EmitContext
*ctx
, MonoCompile
*cfg
, LLVMValueRef method
, const char *name
)
8865 MonoLLVMModule
*module
= ctx
->module
;
8866 MonoDebugMethodInfo
*minfo
= ctx
->minfo
;
8867 char *source_file
, *dir
, *filename
;
8868 LLVMValueRef md
, args
[16], ctx_args
[16], md_args
[64], type_args
[16], ctx_md
, type_md
;
8869 MonoSymSeqPoint
*sym_seq_points
;
8875 mono_debug_symfile_get_seq_points (minfo
, &source_file
, NULL
, NULL
, &sym_seq_points
, &n_seq_points
);
8877 source_file
= g_strdup ("<unknown>");
8878 dir
= g_path_get_dirname (source_file
);
8879 filename
= g_path_get_basename (source_file
);
8881 #if LLVM_API_VERSION > 100
8882 return mono_llvm_di_create_function (module
->di_builder
, module
->cu
, cfg
->method
->name
, name
, dir
, filename
, n_seq_points
? sym_seq_points
[0].line
: 1);
8885 ctx_args
[0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE
);
8886 args
[0] = md_string (filename
);
8887 args
[1] = md_string (dir
);
8888 ctx_args
[1] = LLVMMDNode (args
, 2);
8889 ctx_md
= LLVMMDNode (ctx_args
, 2);
8891 type_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type
, FALSE
);
8892 type_args
[1] = NULL
;
8893 type_args
[2] = NULL
;
8894 type_args
[3] = LLVMMDString ("", 0);
8895 type_args
[4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8896 type_args
[5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8897 type_args
[6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8898 type_args
[7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE
);
8899 type_args
[8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8900 type_args
[9] = NULL
;
8901 type_args
[10] = NULL
;
8902 type_args
[11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8903 type_args
[12] = NULL
;
8904 type_args
[13] = NULL
;
8905 type_args
[14] = NULL
;
8906 type_md
= LLVMMDNode (type_args
, 14);
8908 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8909 md_args
[0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram
, FALSE
);
8910 /* Source directory + file pair */
8911 args
[0] = md_string (filename
);
8912 args
[1] = md_string (dir
);
8913 md_args
[1] = LLVMMDNode (args
,2);
8914 md_args
[2] = ctx_md
;
8915 md_args
[3] = md_string (cfg
->method
->name
);
8916 md_args
[4] = md_string (name
);
8917 md_args
[5] = md_string (name
);
8920 md_args
[6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points
[0].line
, FALSE
);
8922 md_args
[6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8924 md_args
[7] = type_md
;
8926 md_args
[8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
8928 md_args
[9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
8930 md_args
[10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
8931 /* Index into a virtual function */
8932 md_args
[11] = NULL
;
8933 md_args
[12] = NULL
;
8935 md_args
[13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
8937 md_args
[14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE
);
8938 /* Pointer to LLVM function */
8939 md_args
[15] = method
;
8940 /* Function template parameter */
8941 md_args
[16] = NULL
;
8942 /* Function declaration descriptor */
8943 md_args
[17] = NULL
;
8944 /* List of function variables */
8945 md_args
[18] = LLVMMDNode (args
, 0);
8947 md_args
[19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE
);
8948 md
= LLVMMDNode (md_args
, 20);
8950 if (!module
->subprogram_mds
)
8951 module
->subprogram_mds
= g_ptr_array_new ();
8952 g_ptr_array_add (module
->subprogram_mds
, md
);
8956 g_free (source_file
);
8957 g_free (sym_seq_points
);
8963 emit_dbg_loc (EmitContext
*ctx
, LLVMBuilderRef builder
, const unsigned char *cil_code
)
8965 MonoCompile
*cfg
= ctx
->cfg
;
8967 if (ctx
->minfo
&& cil_code
&& cil_code
>= cfg
->header
->code
&& cil_code
< cfg
->header
->code
+ cfg
->header
->code_size
) {
8968 MonoDebugSourceLocation
*loc
;
8969 LLVMValueRef loc_md
;
8971 loc
= mono_debug_symfile_lookup_location (ctx
->minfo
, cil_code
- cfg
->header
->code
);
8974 #if LLVM_API_VERSION > 100
8975 loc_md
= mono_llvm_di_create_location (ctx
->module
->di_builder
, ctx
->dbg_md
, loc
->row
, loc
->column
);
8976 mono_llvm_di_set_location (builder
, loc_md
);
8978 LLVMValueRef md_args
[16];
8982 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->row
, FALSE
);
8983 md_args
[nmd_args
++] = LLVMConstInt (LLVMInt32Type (), loc
->column
, FALSE
);
8984 md_args
[nmd_args
++] = ctx
->dbg_md
;
8985 md_args
[nmd_args
++] = NULL
;
8986 loc_md
= LLVMMDNode (md_args
, nmd_args
);
8987 LLVMSetCurrentDebugLocation (builder
, loc_md
);
8989 mono_debug_symfile_free_location (loc
);
8995 default_mono_llvm_unhandled_exception (void)
8997 MonoJitTlsData
*jit_tls
= mono_get_jit_tls ();
8998 MonoObject
*target
= mono_gchandle_get_target (jit_tls
->thrown_exc
);
9000 mono_unhandled_exception (target
);
9001 exit (mono_environment_exitcode_get ());
9006 - Emit LLVM IR from the mono IR using the LLVM C API.
9007 - The original arch specific code remains, so we can fall back to it if we run
9008 into something we can't handle.
9012 A partial list of issues:
9013 - Handling of opcodes which can throw exceptions.
9015 In the mono JIT, these are implemented using code like this:
9022 push throw_pos - method
9023 call <exception trampoline>
9025 The problematic part is push throw_pos - method, which cannot be represented
9026 in the LLVM IR, since it does not support label values.
9027 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9028 be implemented in JIT mode ?
9029 -> a possible but slower implementation would use the normal exception
9030 throwing code but it would need to control the placement of the throw code
9031 (it needs to be exactly after the compare+branch).
9032 -> perhaps add a PC offset intrinsics ?
9034 - efficient implementation of .ovf opcodes.
9036 These are currently implemented as:
9037 <ins which sets the condition codes>
9040 Some overflow opcodes are now supported by LLVM SVN.
9042 - exception handling, unwinding.
9043 - SSA is disabled for methods with exception handlers
9044 - How to obtain unwind info for LLVM compiled methods ?
9045 -> this is now solved by converting the unwind info generated by LLVM
9047 - LLVM uses the c++ exception handling framework, while we use our home grown
9048 code, and couldn't use the c++ one:
9049 - its not supported under VC++, other exotic platforms.
9050 - it might be impossible to support filter clauses with it.
9054 The trampolines need a predictable call sequence, since they need to disasm
9055 the calling code to obtain register numbers / offsets.
9057 LLVM currently generates this code in non-JIT mode:
9058 mov -0x98(%rax),%eax
9060 Here, the vtable pointer is lost.
9061 -> solution: use one vtable trampoline per class.
9063 - passing/receiving the IMT pointer/RGCTX.
9064 -> solution: pass them as normal arguments ?
9068 LLVM does not allow the specification of argument registers etc. This means
9069 that all calls are made according to the platform ABI.
9071 - passing/receiving vtypes.
9073 Vtypes passed/received in registers are handled by the front end by using
9074 a signature with scalar arguments, and loading the parts of the vtype into those
9077 Vtypes passed on the stack are handled using the 'byval' attribute.
9081 Supported though alloca, we need to emit the load/store code.
9085 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9086 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9087 This is made easier because the IR is already in SSA form.
9088 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9089 types are frequently used incorrectly.
9094 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9095 it with the file containing the methods emitted by the JIT and the AOT data
9099 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9100 * - each bblock should end with a branch
9101 * - setting the return value, making cfg->ret non-volatile
9102 * - avoid some transformations in the JIT which make it harder for us to generate
9104 * - use pointer types to help optimizations.