2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
11 #ifndef __STDC_LIMIT_MACROS
12 #define __STDC_LIMIT_MACROS
14 #ifndef __STDC_CONSTANT_MACROS
15 #define __STDC_CONSTANT_MACROS
18 #include "llvm-c/Core.h"
19 #include "llvm-c/ExecutionEngine.h"
20 #include "llvm-c/BitWriter.h"
21 #include "llvm-c/Analysis.h"
23 #include "mini-llvm-cpp.h"
26 * Information associated by mono with LLVM modules.
30 LLVMValueRef
throw, rethrow
, throw_corlib_exception
;
31 GHashTable
*llvm_types
;
33 const char *got_symbol
;
34 GHashTable
*plt_entries
;
38 * Information associated by the backend with mono basic blocks.
41 LLVMBasicBlockRef bblock
, end_bblock
;
42 LLVMValueRef finally_ind
;
43 gboolean added
, invoke_target
;
45 * If this bblock is the start of a finally clause, this is a list of bblocks it
46 * needs to branch to in ENDFINALLY.
48 GSList
*call_handler_return_bbs
;
49 LLVMValueRef endfinally_switch
;
54 * Structure containing emit state
59 /* Maps method names to the corresponding LLVMValueRef */
60 GHashTable
*emitted_method_decls
;
64 MonoLLVMModule
*lmodule
;
67 int sindex
, default_index
, ex_index
;
68 LLVMBuilderRef builder
;
69 LLVMValueRef
*values
, *addresses
;
70 MonoType
**vreg_cli_types
;
72 MonoMethodSignature
*sig
;
74 GHashTable
*region_to_handler
;
75 LLVMBuilderRef alloca_builder
;
76 LLVMValueRef last_alloca
;
77 LLVMValueRef rgctx_arg
;
85 MonoBasicBlock
*in_bb
;
90 * Instruction metadata
91 * This is the same as ins_info, but LREG != IREG.
99 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
100 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
107 /* keep in sync with the enum in mini.h */
110 #include "mini-ops.h"
115 #if SIZEOF_VOID_P == 4
116 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
118 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
121 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
124 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
126 #define TRACE_FAILURE(msg)
129 #define LLVM_FAILURE(ctx, reason) do { \
130 TRACE_FAILURE (reason); \
131 (ctx)->cfg->exception_message = g_strdup (reason); \
132 (ctx)->cfg->disable_llvm = TRUE; \
136 #define CHECK_FAILURE(ctx) do { \
137 if ((ctx)->cfg->disable_llvm) \
141 static LLVMIntPredicate cond_to_llvm_cond
[] = {
154 static LLVMRealPredicate fpcond_to_llvm_cond
[] = {
167 static LLVMExecutionEngineRef ee
;
168 static guint32 current_cfg_tls_id
;
170 static MonoLLVMModule jit_module
, aot_module
;
171 static gboolean jit_module_inited
;
172 static int memset_param_count
, memcpy_param_count
;
173 static const char *memset_func_name
;
174 static const char *memcpy_func_name
;
175 static const char *eh_selector_name
;
177 static void init_jit_module (void);
182 * The LLVM type with width == sizeof (gpointer)
187 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
190 #if !LLVM_CHECK_VERSION(2, 8)
192 static LLVMValueRef
LLVMBuildFAdd(LLVMBuilderRef Builder
,
193 LLVMValueRef LHS
, LLVMValueRef RHS
,
196 return LLVMBuildAdd (Builder
, LHS
, RHS
, Name
);
199 static LLVMValueRef
LLVMBuildFSub(LLVMBuilderRef Builder
,
200 LLVMValueRef LHS
, LLVMValueRef RHS
,
203 return LLVMBuildSub (Builder
, LHS
, RHS
, Name
);
206 static LLVMValueRef
LLVMBuildFMul(LLVMBuilderRef Builder
,
207 LLVMValueRef LHS
, LLVMValueRef RHS
,
210 return LLVMBuildMul (Builder
, LHS
, RHS
, Name
);
218 * Return the size of the LLVM representation of the vtype T.
221 get_vtype_size (MonoType
*t
)
225 size
= mono_class_value_size (mono_class_from_mono_type (t
), NULL
);
227 while (size
< sizeof (gpointer
) && mono_is_power_of_two (size
) == -1)
234 * simd_class_to_llvm_type:
236 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
239 simd_class_to_llvm_type (EmitContext
*ctx
, MonoClass
*klass
)
241 if (!strcmp (klass
->name
, "Vector2d")) {
242 return LLVMVectorType (LLVMDoubleType (), 2);
243 } else if (!strcmp (klass
->name
, "Vector2l")) {
244 return LLVMVectorType (LLVMInt64Type (), 2);
245 } else if (!strcmp (klass
->name
, "Vector2ul")) {
246 return LLVMVectorType (LLVMInt64Type (), 2);
247 } else if (!strcmp (klass
->name
, "Vector4i")) {
248 return LLVMVectorType (LLVMInt32Type (), 4);
249 } else if (!strcmp (klass
->name
, "Vector4ui")) {
250 return LLVMVectorType (LLVMInt32Type (), 4);
251 } else if (!strcmp (klass
->name
, "Vector4f")) {
252 return LLVMVectorType (LLVMFloatType (), 4);
253 } else if (!strcmp (klass
->name
, "Vector8s")) {
254 return LLVMVectorType (LLVMInt16Type (), 8);
255 } else if (!strcmp (klass
->name
, "Vector8us")) {
256 return LLVMVectorType (LLVMInt16Type (), 8);
257 } else if (!strcmp (klass
->name
, "Vector16sb")) {
258 return LLVMVectorType (LLVMInt8Type (), 16);
259 } else if (!strcmp (klass
->name
, "Vector16b")) {
260 return LLVMVectorType (LLVMInt8Type (), 16);
262 printf ("%s\n", klass
->name
);
271 * Return the LLVM type corresponding to T.
274 type_to_llvm_type (EmitContext
*ctx
, MonoType
*t
)
277 return LLVMPointerType (LLVMInt8Type (), 0);
280 return LLVMVoidType ();
282 return LLVMInt8Type ();
284 return LLVMInt16Type ();
286 return LLVMInt32Type ();
288 return LLVMInt8Type ();
290 return LLVMInt16Type ();
292 return LLVMInt32Type ();
293 case MONO_TYPE_BOOLEAN
:
294 return LLVMInt8Type ();
297 return LLVMInt64Type ();
299 return LLVMInt16Type ();
301 return LLVMFloatType ();
303 return LLVMDoubleType ();
306 return IntPtrType ();
307 case MONO_TYPE_OBJECT
:
308 case MONO_TYPE_CLASS
:
309 case MONO_TYPE_ARRAY
:
310 case MONO_TYPE_SZARRAY
:
311 case MONO_TYPE_STRING
:
313 return LLVMPointerType (IntPtrType (), 0);
316 /* Because of generic sharing */
317 return IntPtrType ();
318 case MONO_TYPE_GENERICINST
:
319 if (!mono_type_generic_inst_is_valuetype (t
))
320 return IntPtrType ();
322 case MONO_TYPE_VALUETYPE
:
323 case MONO_TYPE_TYPEDBYREF
: {
327 klass
= mono_class_from_mono_type (t
);
329 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, klass
))
330 return simd_class_to_llvm_type (ctx
, klass
);
333 return type_to_llvm_type (ctx
, mono_class_enum_basetype (klass
));
334 ltype
= g_hash_table_lookup (ctx
->lmodule
->llvm_types
, klass
);
337 LLVMTypeRef
*eltypes
;
339 size
= get_vtype_size (t
);
341 eltypes
= g_new (LLVMTypeRef
, size
);
342 for (i
= 0; i
< size
; ++i
)
343 eltypes
[i
] = LLVMInt8Type ();
345 ltype
= LLVMStructType (eltypes
, size
, FALSE
);
346 g_hash_table_insert (ctx
->lmodule
->llvm_types
, klass
, ltype
);
353 printf ("X: %d\n", t
->type
);
354 ctx
->cfg
->exception_message
= g_strdup_printf ("type %s", mono_type_full_name (t
));
355 ctx
->cfg
->disable_llvm
= TRUE
;
363 * Return whenever T is an unsigned int type.
366 type_is_unsigned (EmitContext
*ctx
, MonoType
*t
)
382 * type_to_llvm_arg_type:
384 * Same as type_to_llvm_type, but treat i8/i16 as i32.
387 type_to_llvm_arg_type (EmitContext
*ctx
, MonoType
*t
)
389 LLVMTypeRef ptype
= type_to_llvm_type (ctx
, t
);
391 if (ptype
== LLVMInt8Type () || ptype
== LLVMInt16Type ()) {
393 * LLVM generates code which only sets the lower bits, while JITted
394 * code expects all the bits to be set.
396 ptype
= LLVMInt32Type ();
403 * llvm_type_to_stack_type:
405 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
408 static G_GNUC_UNUSED LLVMTypeRef
409 llvm_type_to_stack_type (LLVMTypeRef type
)
413 if (type
== LLVMInt8Type ())
414 return LLVMInt32Type ();
415 else if (type
== LLVMInt16Type ())
416 return LLVMInt32Type ();
417 else if (type
== LLVMFloatType ())
418 return LLVMDoubleType ();
424 * regtype_to_llvm_type:
426 * Return the LLVM type corresponding to the regtype C used in instruction
430 regtype_to_llvm_type (char c
)
434 return LLVMInt32Type ();
436 return LLVMInt64Type ();
438 return LLVMDoubleType ();
447 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
450 op_to_llvm_type (int opcode
)
455 return LLVMInt8Type ();
458 return LLVMInt8Type ();
461 return LLVMInt16Type ();
464 return LLVMInt16Type ();
467 return LLVMInt32Type ();
470 return LLVMInt32Type ();
472 return LLVMInt64Type ();
474 return LLVMFloatType ();
476 return LLVMDoubleType ();
478 return LLVMInt64Type ();
480 return LLVMInt32Type ();
482 return LLVMInt64Type ();
485 return LLVMInt8Type ();
488 return LLVMInt16Type ();
491 return sizeof (gpointer
) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
498 return LLVMInt32Type ();
505 return LLVMInt64Type ();
507 printf ("%s\n", mono_inst_name (opcode
));
508 g_assert_not_reached ();
514 * load_store_to_llvm_type:
516 * Return the size/sign/zero extension corresponding to the load/store opcode
520 load_store_to_llvm_type (int opcode
, int *size
, gboolean
*sext
, gboolean
*zext
)
526 case OP_LOADI1_MEMBASE
:
527 case OP_STOREI1_MEMBASE_REG
:
528 case OP_STOREI1_MEMBASE_IMM
:
531 return LLVMInt8Type ();
532 case OP_LOADU1_MEMBASE
:
536 return LLVMInt8Type ();
537 case OP_LOADI2_MEMBASE
:
538 case OP_STOREI2_MEMBASE_REG
:
539 case OP_STOREI2_MEMBASE_IMM
:
542 return LLVMInt16Type ();
543 case OP_LOADU2_MEMBASE
:
547 return LLVMInt16Type ();
548 case OP_LOADI4_MEMBASE
:
549 case OP_LOADU4_MEMBASE
:
552 case OP_STOREI4_MEMBASE_REG
:
553 case OP_STOREI4_MEMBASE_IMM
:
555 return LLVMInt32Type ();
556 case OP_LOADI8_MEMBASE
:
558 case OP_STOREI8_MEMBASE_REG
:
559 case OP_STOREI8_MEMBASE_IMM
:
561 return LLVMInt64Type ();
562 case OP_LOADR4_MEMBASE
:
563 case OP_STORER4_MEMBASE_REG
:
565 return LLVMFloatType ();
566 case OP_LOADR8_MEMBASE
:
567 case OP_STORER8_MEMBASE_REG
:
569 return LLVMDoubleType ();
570 case OP_LOAD_MEMBASE
:
572 case OP_STORE_MEMBASE_REG
:
573 case OP_STORE_MEMBASE_IMM
:
574 *size
= sizeof (gpointer
);
575 return IntPtrType ();
577 g_assert_not_reached ();
585 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
588 ovf_op_to_intrins (int opcode
)
592 return "llvm.sadd.with.overflow.i32";
594 return "llvm.uadd.with.overflow.i32";
596 return "llvm.ssub.with.overflow.i32";
598 return "llvm.usub.with.overflow.i32";
600 return "llvm.smul.with.overflow.i32";
602 return "llvm.umul.with.overflow.i32";
604 return "llvm.sadd.with.overflow.i64";
606 return "llvm.uadd.with.overflow.i64";
608 return "llvm.ssub.with.overflow.i64";
610 return "llvm.usub.with.overflow.i64";
612 return "llvm.smul.with.overflow.i64";
614 return "llvm.umul.with.overflow.i64";
616 g_assert_not_reached ();
622 simd_op_to_intrins (int opcode
)
625 #if defined(TARGET_X86) || defined(TARGET_AMD64)
627 return "llvm.x86.sse2.min.pd";
629 return "llvm.x86.sse2.min.ps";
631 return "llvm.x86.sse41.pminud";
633 return "llvm.x86.sse41.pminuw";
635 return "llvm.x86.sse2.pminu.b";
637 return "llvm.x86.sse2.max.pd";
639 return "llvm.x86.sse2.max.ps";
641 return "llvm.x86.sse41.pmaxud";
643 return "llvm.x86.sse41.pmaxuw";
645 return "llvm.x86.sse2.pmaxu.b";
648 g_assert_not_reached ();
656 * Return the LLVM basic block corresponding to BB.
658 static LLVMBasicBlockRef
659 get_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
663 if (ctx
->bblocks
[bb
->block_num
].bblock
== NULL
) {
664 sprintf (bb_name
, "BB%d", bb
->block_num
);
666 ctx
->bblocks
[bb
->block_num
].bblock
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
667 ctx
->bblocks
[bb
->block_num
].end_bblock
= ctx
->bblocks
[bb
->block_num
].bblock
;
670 return ctx
->bblocks
[bb
->block_num
].bblock
;
676 * Return the last LLVM bblock corresponding to BB.
677 * This might not be equal to the bb returned by get_bb () since we need to generate
678 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
680 static LLVMBasicBlockRef
681 get_end_bb (EmitContext
*ctx
, MonoBasicBlock
*bb
)
684 return ctx
->bblocks
[bb
->block_num
].end_bblock
;
687 static LLVMBasicBlockRef
688 gen_bb (EmitContext
*ctx
, const char *prefix
)
692 sprintf (bb_name
, "%s%d", prefix
, ++ ctx
->ex_index
);
693 return LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
699 * Return the target of the patch identified by TYPE and TARGET.
702 resolve_patch (MonoCompile
*cfg
, MonoJumpInfoType type
, gconstpointer target
)
706 memset (&ji
, 0, sizeof (ji
));
708 ji
.data
.target
= target
;
710 return mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, &ji
, FALSE
);
716 * Emit code to convert the LLVM value V to DTYPE.
719 convert_full (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
, gboolean is_unsigned
)
721 LLVMTypeRef stype
= LLVMTypeOf (v
);
723 if (stype
!= dtype
) {
724 gboolean ext
= FALSE
;
727 if (dtype
== LLVMInt64Type () && (stype
== LLVMInt32Type () || stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
729 else if (dtype
== LLVMInt32Type () && (stype
== LLVMInt16Type () || stype
== LLVMInt8Type ()))
731 else if (dtype
== LLVMInt16Type () && (stype
== LLVMInt8Type ()))
735 return is_unsigned
? LLVMBuildZExt (ctx
->builder
, v
, dtype
, "") : LLVMBuildSExt (ctx
->builder
, v
, dtype
, "");
737 if (dtype
== LLVMDoubleType () && stype
== LLVMFloatType ())
738 return LLVMBuildFPExt (ctx
->builder
, v
, dtype
, "");
741 if (stype
== LLVMInt64Type () && (dtype
== LLVMInt32Type () || dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
742 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
743 if (stype
== LLVMInt32Type () && (dtype
== LLVMInt16Type () || dtype
== LLVMInt8Type ()))
744 return LLVMBuildTrunc (ctx
->builder
, v
, dtype
, "");
745 if (stype
== LLVMDoubleType () && dtype
== LLVMFloatType ())
746 return LLVMBuildFPTrunc (ctx
->builder
, v
, dtype
, "");
748 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
&& LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
749 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
750 if (LLVMGetTypeKind (dtype
) == LLVMPointerTypeKind
)
751 return LLVMBuildIntToPtr (ctx
->builder
, v
, dtype
, "");
752 if (LLVMGetTypeKind (stype
) == LLVMPointerTypeKind
)
753 return LLVMBuildPtrToInt (ctx
->builder
, v
, dtype
, "");
755 #ifdef MONO_ARCH_SOFT_FLOAT
756 if (stype
== LLVMInt32Type () && dtype
== LLVMFloatType ())
757 return LLVMBuildBitCast (ctx
->builder
, v
, dtype
, "");
758 if (stype
== LLVMInt32Type () && dtype
== LLVMDoubleType ())
759 return LLVMBuildBitCast (ctx
->builder
, LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), ""), dtype
, "");
763 LLVMDumpValue (LLVMConstNull (dtype
));
764 g_assert_not_reached ();
772 convert (EmitContext
*ctx
, LLVMValueRef v
, LLVMTypeRef dtype
)
774 return convert_full (ctx
, v
, dtype
, FALSE
);
778 * emit_volatile_load:
780 * If vreg is volatile, emit a load from its address.
783 emit_volatile_load (EmitContext
*ctx
, int vreg
)
787 LLVMValueRef v
= LLVMBuildLoad (ctx
->builder
, ctx
->addresses
[vreg
], "");
788 t
= ctx
->vreg_cli_types
[vreg
];
789 if (t
&& !t
->byref
) {
791 * Might have to zero extend since llvm doesn't have
794 if (t
->type
== MONO_TYPE_U1
|| t
->type
== MONO_TYPE_U2
)
795 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt32Type (), "");
796 else if (t
->type
== MONO_TYPE_U8
)
797 v
= LLVMBuildZExt (ctx
->builder
, v
, LLVMInt64Type (), "");
804 * emit_volatile_store:
806 * If VREG is volatile, emit a store from its value to its address.
809 emit_volatile_store (EmitContext
*ctx
, int vreg
)
811 MonoInst
*var
= get_vreg_to_inst (ctx
->cfg
, vreg
);
813 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
814 g_assert (ctx
->addresses
[vreg
]);
815 LLVMBuildStore (ctx
->builder
, convert (ctx
, ctx
->values
[vreg
], type_to_llvm_type (ctx
, var
->inst_vtype
)), ctx
->addresses
[vreg
]);
822 * Return the LLVM signature corresponding to the mono signature SIG using the
823 * calling convention information in CINFO.
826 sig_to_llvm_sig (EmitContext
*ctx
, MonoMethodSignature
*sig
, LLVMCallInfo
*cinfo
)
828 LLVMTypeRef ret_type
;
829 LLVMTypeRef
*param_types
= NULL
;
832 gboolean vretaddr
= FALSE
;
834 ret_type
= type_to_llvm_type (ctx
, sig
->ret
);
837 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
838 /* LLVM models this by returning an aggregate value */
839 if (cinfo
->ret
.pair_storage
[0] == LLVMArgInIReg
&& cinfo
->ret
.pair_storage
[1] == LLVMArgNone
) {
840 LLVMTypeRef members
[2];
842 members
[0] = IntPtrType ();
843 ret_type
= LLVMStructType (members
, 1, FALSE
);
845 g_assert_not_reached ();
847 } else if (cinfo
&& MONO_TYPE_ISSTRUCT (sig
->ret
)) {
848 g_assert (cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
);
852 param_types
= g_new0 (LLVMTypeRef
, (sig
->param_count
* 2) + 2);
854 if (cinfo
&& cinfo
->rgctx_arg
) {
855 param_types
[pindex
] = IntPtrType ();
858 if (cinfo
&& cinfo
->imt_arg
) {
859 param_types
[pindex
] = IntPtrType ();
863 ret_type
= LLVMVoidType ();
864 param_types
[pindex
++] = IntPtrType ();
867 param_types
[pindex
++] = IntPtrType ();
868 for (i
= 0; i
< sig
->param_count
; ++i
) {
869 if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeInReg
) {
870 for (j
= 0; j
< 2; ++j
) {
871 switch (cinfo
->args
[i
+ sig
->hasthis
].pair_storage
[j
]) {
873 param_types
[pindex
++] = LLVMIntType (sizeof (gpointer
) * 8);
878 g_assert_not_reached ();
881 } else if (cinfo
&& cinfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
) {
882 param_types
[pindex
] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
884 param_types
[pindex
] = LLVMPointerType (param_types
[pindex
], 0);
887 param_types
[pindex
++] = type_to_llvm_arg_type (ctx
, sig
->params
[i
]);
892 res
= LLVMFunctionType (ret_type
, param_types
, pindex
, FALSE
);
893 g_free (param_types
);
898 g_free (param_types
);
906 * Create an LLVM function type from the arguments.
908 static G_GNUC_UNUSED LLVMTypeRef
909 LLVMFunctionType1(LLVMTypeRef ReturnType
,
910 LLVMTypeRef ParamType1
,
913 LLVMTypeRef param_types
[1];
915 param_types
[0] = ParamType1
;
917 return LLVMFunctionType (ReturnType
, param_types
, 1, IsVarArg
);
923 * Create an LLVM function type from the arguments.
926 LLVMFunctionType2(LLVMTypeRef ReturnType
,
927 LLVMTypeRef ParamType1
,
928 LLVMTypeRef ParamType2
,
931 LLVMTypeRef param_types
[2];
933 param_types
[0] = ParamType1
;
934 param_types
[1] = ParamType2
;
936 return LLVMFunctionType (ReturnType
, param_types
, 2, IsVarArg
);
942 * Create an LLVM function type from the arguments.
945 LLVMFunctionType3(LLVMTypeRef ReturnType
,
946 LLVMTypeRef ParamType1
,
947 LLVMTypeRef ParamType2
,
948 LLVMTypeRef ParamType3
,
951 LLVMTypeRef param_types
[3];
953 param_types
[0] = ParamType1
;
954 param_types
[1] = ParamType2
;
955 param_types
[2] = ParamType3
;
957 return LLVMFunctionType (ReturnType
, param_types
, 3, IsVarArg
);
963 * Create an LLVM builder and remember it so it can be freed later.
965 static LLVMBuilderRef
966 create_builder (EmitContext
*ctx
)
968 LLVMBuilderRef builder
= LLVMCreateBuilder ();
970 ctx
->builders
= g_slist_prepend_mempool (ctx
->cfg
->mempool
, ctx
->builders
, builder
);
976 get_plt_entry (EmitContext
*ctx
, LLVMTypeRef llvm_sig
, MonoJumpInfoType type
, gconstpointer data
)
978 char *callee_name
= mono_aot_get_plt_symbol (type
, data
);
985 callee
= g_hash_table_lookup (ctx
->lmodule
->plt_entries
, callee_name
);
987 callee
= LLVMAddFunction (ctx
->module
, callee_name
, llvm_sig
);
989 LLVMSetVisibility (callee
, LLVMHiddenVisibility
);
991 g_hash_table_insert (ctx
->lmodule
->plt_entries
, (char*)callee_name
, callee
);
998 emit_cond_throw_pos (EmitContext
*ctx
)
1003 get_handler_clause (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
1005 MonoMethodHeader
*header
= cfg
->header
;
1006 MonoExceptionClause
*clause
;
1010 if (bb
->region
!= -1 && MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))
1011 return (bb
->region
>> 8) - 1;
1014 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1015 clause
= &header
->clauses
[i
];
1017 if (MONO_OFFSET_IN_CLAUSE (clause
, bb
->real_offset
) && clause
->flags
== MONO_EXCEPTION_CLAUSE_NONE
)
1027 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1031 emit_call (EmitContext
*ctx
, MonoBasicBlock
*bb
, LLVMBuilderRef
*builder_ref
, LLVMValueRef callee
, LLVMValueRef
*args
, int pindex
)
1033 MonoCompile
*cfg
= ctx
->cfg
;
1035 LLVMBuilderRef builder
= *builder_ref
;
1038 clause_index
= get_handler_clause (cfg
, bb
);
1040 if (clause_index
!= -1) {
1041 MonoMethodHeader
*header
= cfg
->header
;
1042 MonoExceptionClause
*ec
= &header
->clauses
[clause_index
];
1043 MonoBasicBlock
*tblock
;
1044 LLVMBasicBlockRef ex_bb
, noex_bb
;
1047 * Have to use an invoke instead of a call, branching to the
1048 * handler bblock of the clause containing this bblock.
1051 g_assert (ec
->flags
== MONO_EXCEPTION_CLAUSE_NONE
|| ec
->flags
== MONO_EXCEPTION_CLAUSE_FINALLY
);
1053 tblock
= cfg
->cil_offset_to_bb
[ec
->handler_offset
];
1056 ctx
->bblocks
[tblock
->block_num
].invoke_target
= TRUE
;
1058 ex_bb
= get_bb (ctx
, tblock
);
1060 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1063 lcall
= LLVMBuildInvoke (builder
, callee
, args
, pindex
, noex_bb
, ex_bb
, "");
1065 builder
= ctx
->builder
= create_builder (ctx
);
1066 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1068 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1070 lcall
= LLVMBuildCall (builder
, callee
, args
, pindex
, "");
1071 ctx
->builder
= builder
;
1074 *builder_ref
= ctx
->builder
;
1080 * emit_cond_system_exception:
1082 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1083 * Might set the ctx exception.
1086 emit_cond_system_exception (EmitContext
*ctx
, MonoBasicBlock
*bb
, const char *exc_type
, LLVMValueRef cmp
)
1088 LLVMBasicBlockRef ex_bb
, noex_bb
;
1089 LLVMBuilderRef builder
;
1090 MonoClass
*exc_class
;
1091 LLVMValueRef args
[2];
1093 ex_bb
= gen_bb (ctx
, "EX_BB");
1094 noex_bb
= gen_bb (ctx
, "NOEX_BB");
1096 LLVMBuildCondBr (ctx
->builder
, cmp
, ex_bb
, noex_bb
);
1098 exc_class
= mono_class_from_name (mono_defaults
.corlib
, "System", exc_type
);
1099 g_assert (exc_class
);
1101 /* Emit exception throwing code */
1102 builder
= create_builder (ctx
);
1103 LLVMPositionBuilderAtEnd (builder
, ex_bb
);
1105 if (!ctx
->lmodule
->throw_corlib_exception
) {
1106 LLVMValueRef callee
;
1109 MonoMethodSignature
*throw_sig
= mono_metadata_signature_alloc (mono_defaults
.corlib
, 2);
1110 throw_sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1111 throw_sig
->params
[0] = &mono_defaults
.int32_class
->byval_arg
;
1112 throw_sig
->params
[1] = &mono_defaults
.int32_class
->byval_arg
;
1113 sig
= sig_to_llvm_sig (ctx
, throw_sig
, NULL
);
1115 if (ctx
->cfg
->compile_aot
) {
1116 callee
= get_plt_entry (ctx
, sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, "mono_arch_throw_corlib_exception");
1118 callee
= LLVMAddFunction (ctx
->module
, "throw_corlib_exception", sig_to_llvm_sig (ctx
, throw_sig
, NULL
));
1122 * LLVM generated code doesn't push the arguments, so we need another
1125 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, "mono_arch_llvm_throw_corlib_exception"));
1127 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (ctx
->cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, "mono_arch_throw_corlib_exception"));
1131 mono_memory_barrier ();
1132 ctx
->lmodule
->throw_corlib_exception
= callee
;
1136 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
- MONO_TOKEN_TYPE_DEF
, FALSE
);
1138 args
[0] = LLVMConstInt (LLVMInt32Type (), exc_class
->type_token
, FALSE
);
1142 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1143 * otherwise only the line numbers in stack traces are incorrect.
1145 if (bb
->region
!= -1)
1146 LLVM_FAILURE (ctx
, "system-ex-in-region");
1148 args
[1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1149 emit_call (ctx
, bb
, &builder
, ctx
->lmodule
->throw_corlib_exception
, args
, 2);
1151 LLVMBuildUnreachable (builder
);
1153 ctx
->builder
= create_builder (ctx
);
1154 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
1156 ctx
->bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
1166 * emit_reg_to_vtype:
1168 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1171 emit_reg_to_vtype (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
)
1175 size
= get_vtype_size (t
);
1177 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1178 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1181 for (j
= 0; j
< 2; ++j
) {
1182 LLVMValueRef index
[2], addr
;
1183 int part_size
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1184 LLVMTypeRef part_type
;
1186 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1189 part_type
= LLVMIntType (part_size
* 8);
1190 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1191 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1192 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1194 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1195 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1196 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1198 switch (ainfo
->pair_storage
[j
]) {
1200 LLVMBuildStore (builder
, convert (ctx
, regs
[j
], part_type
), LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (part_type
, 0), ""));
1205 g_assert_not_reached ();
1208 size
-= sizeof (gpointer
);
1213 * emit_vtype_to_reg:
1215 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1216 * into REGS, and the number of registers into NREGS.
1219 emit_vtype_to_reg (EmitContext
*ctx
, LLVMBuilderRef builder
, MonoType
*t
, LLVMValueRef address
, LLVMArgInfo
*ainfo
, LLVMValueRef
*regs
, guint32
*nregs
)
1224 size
= get_vtype_size (t
);
1226 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1227 address
= LLVMBuildBitCast (ctx
->builder
, address
, LLVMPointerType (LLVMInt8Type (), 0), "");
1230 for (j
= 0; j
< 2; ++j
) {
1231 LLVMValueRef index
[2], addr
;
1232 int partsize
= size
> sizeof (gpointer
) ? sizeof (gpointer
) : size
;
1234 if (ainfo
->pair_storage
[j
] == LLVMArgNone
)
1237 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (t
))) {
1238 index
[0] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1239 addr
= LLVMBuildGEP (builder
, address
, index
, 1, "");
1241 index
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
1242 index
[1] = LLVMConstInt (LLVMInt32Type (), j
* sizeof (gpointer
), FALSE
);
1243 addr
= LLVMBuildGEP (builder
, address
, index
, 2, "");
1245 switch (ainfo
->pair_storage
[j
]) {
1247 regs
[pindex
++] = convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (ctx
->builder
, addr
, LLVMPointerType (LLVMIntType (partsize
* 8), 0), ""), ""), IntPtrType ());
1252 g_assert_not_reached ();
1254 size
-= sizeof (gpointer
);
1261 build_alloca (EmitContext
*ctx
, MonoType
*t
)
1263 MonoClass
*k
= mono_class_from_mono_type (t
);
1266 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, k
))
1269 align
= mono_class_min_align (k
);
1271 /* Sometimes align is not a power of 2 */
1272 while (mono_is_power_of_two (align
) == -1)
1276 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1277 * get executed every time control reaches them.
1279 LLVMPositionBuilder (ctx
->alloca_builder
, get_bb (ctx
, ctx
->cfg
->bb_entry
), ctx
->last_alloca
);
1281 ctx
->last_alloca
= mono_llvm_build_alloca (ctx
->alloca_builder
, type_to_llvm_type (ctx
, t
), NULL
, align
, "");
1282 return ctx
->last_alloca
;
1286 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1289 mark_as_used (LLVMModuleRef module
, LLVMValueRef global
)
1291 LLVMTypeRef used_type
;
1292 LLVMValueRef used
, used_elem
;
1294 used_type
= LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1295 used
= LLVMAddGlobal (module
, used_type
, "llvm.used");
1296 used_elem
= LLVMConstBitCast (global
, LLVMPointerType (LLVMInt8Type (), 0));
1297 LLVMSetInitializer (used
, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem
, 1));
1298 LLVMSetLinkage (used
, LLVMAppendingLinkage
);
1299 LLVMSetSection (used
, "llvm.metadata");
1305 * Emit code to load/convert arguments.
1308 emit_entry_bb (EmitContext
*ctx
, LLVMBuilderRef builder
, int *pindexes
)
1311 MonoCompile
*cfg
= ctx
->cfg
;
1312 MonoMethodSignature
*sig
= ctx
->sig
;
1313 LLVMCallInfo
*linfo
= ctx
->linfo
;
1316 ctx
->alloca_builder
= create_builder (ctx
);
1319 * Handle indirect/volatile variables by allocating memory for them
1320 * using 'alloca', and storing their address in a temporary.
1322 for (i
= 0; i
< cfg
->num_varinfo
; ++i
) {
1323 MonoInst
*var
= cfg
->varinfo
[i
];
1326 if (var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
) || MONO_TYPE_ISSTRUCT (var
->inst_vtype
)) {
1327 vtype
= type_to_llvm_type (ctx
, var
->inst_vtype
);
1328 CHECK_FAILURE (ctx
);
1329 /* Could be already created by an OP_VPHI */
1330 if (!ctx
->addresses
[var
->dreg
])
1331 ctx
->addresses
[var
->dreg
] = build_alloca (ctx
, var
->inst_vtype
);
1332 ctx
->vreg_cli_types
[var
->dreg
] = var
->inst_vtype
;
1336 for (i
= 0; i
< sig
->param_count
; ++i
) {
1337 LLVMArgInfo
*ainfo
= &linfo
->args
[i
+ sig
->hasthis
];
1338 int reg
= cfg
->args
[i
+ sig
->hasthis
]->dreg
;
1340 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
1341 LLVMValueRef regs
[2];
1344 * Emit code to save the argument from the registers to
1345 * the real argument.
1347 pindex
= pindexes
[i
];
1348 regs
[0] = LLVMGetParam (ctx
->lmethod
, pindex
);
1349 if (ainfo
->pair_storage
[1] != LLVMArgNone
)
1350 regs
[1] = LLVMGetParam (ctx
->lmethod
, pindex
+ 1);
1354 ctx
->addresses
[reg
] = build_alloca (ctx
, sig
->params
[i
]);
1356 emit_reg_to_vtype (ctx
, builder
, sig
->params
[i
], ctx
->addresses
[reg
], ainfo
, regs
);
1358 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1359 /* Treat these as normal values */
1360 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1362 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
1363 ctx
->addresses
[reg
] = LLVMGetParam (ctx
->lmethod
, pindexes
[i
]);
1365 if (MONO_CLASS_IS_SIMD (ctx
->cfg
, mono_class_from_mono_type (sig
->params
[i
]))) {
1366 /* Treat these as normal values */
1367 ctx
->values
[reg
] = LLVMBuildLoad (builder
, ctx
->addresses
[reg
], "");
1370 ctx
->values
[reg
] = convert (ctx
, ctx
->values
[reg
], llvm_type_to_stack_type (type_to_llvm_type (ctx
, sig
->params
[i
])));
1375 emit_volatile_store (ctx
, cfg
->vret_addr
->dreg
);
1377 emit_volatile_store (ctx
, cfg
->args
[0]->dreg
);
1378 for (i
= 0; i
< sig
->param_count
; ++i
)
1379 if (!MONO_TYPE_ISSTRUCT (sig
->params
[i
]))
1380 emit_volatile_store (ctx
, cfg
->args
[i
+ sig
->hasthis
]->dreg
);
1382 if (sig
->hasthis
&& !cfg
->rgctx_var
) {
1383 #if LLVM_CHECK_VERSION (2, 8)
1384 LLVMValueRef this_alloc
, md_arg
;
1388 * The exception handling code needs the location where the this argument was
1389 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1390 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1391 * location into the LSDA.
1393 // FIXME: Do this for gshared only
1394 this_alloc
= mono_llvm_build_alloca (builder
, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE
), 0, "");
1395 /* This volatile store will keep the alloca alive */
1396 mono_llvm_build_store (builder
, ctx
->values
[cfg
->args
[0]->dreg
], this_alloc
, TRUE
);
1398 md_kind
= LLVMGetMDKindID ("mono.this", strlen ("mono.this"));
1399 md_arg
= LLVMMDString ("this", 4);
1400 LLVMSetMetadata (this_alloc
, md_kind
, LLVMMDNode (&md_arg
, 1));
1404 if (cfg
->rgctx_var
) {
1405 LLVMValueRef rgctx_alloc
, store
, md_arg
;
1409 * We handle the rgctx arg similarly to the this pointer.
1411 g_assert (ctx
->addresses
[cfg
->rgctx_var
->dreg
]);
1412 rgctx_alloc
= ctx
->addresses
[cfg
->rgctx_var
->dreg
];
1413 /* This volatile store will keep the alloca alive */
1414 store
= mono_llvm_build_store (builder
, ctx
->rgctx_arg
, rgctx_alloc
, TRUE
);
1416 md_kind
= LLVMGetMDKindID ("mono.this", strlen ("mono.this"));
1417 md_arg
= LLVMMDString ("this", 4);
1418 LLVMSetMetadata (rgctx_alloc
, md_kind
, LLVMMDNode (&md_arg
, 1));
1422 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1423 * it needs to continue normally, or return back to the exception handling system.
1425 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1426 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
))
1427 g_hash_table_insert (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)), bb
);
1428 if (bb
->region
!= -1 && (bb
->flags
& BB_EXCEPTION_HANDLER
) && bb
->in_scount
== 0) {
1429 LLVMValueRef val
= LLVMBuildAlloca (builder
, LLVMInt32Type (), "");
1430 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), val
);
1432 ctx
->bblocks
[bb
->block_num
].finally_ind
= val
;
1440 /* Have to export this for AOT */
1442 mono_personality (void);
1445 mono_personality (void)
1448 g_assert_not_reached ();
1452 * mono_llvm_emit_method:
1454 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
1457 mono_llvm_emit_method (MonoCompile
*cfg
)
1460 MonoMethodSignature
*sig
;
1462 LLVMTypeRef method_type
;
1463 LLVMValueRef method
= NULL
, debug_alias
= NULL
;
1464 char *method_name
, *debug_name
= NULL
;
1465 LLVMValueRef
*values
, *addresses
;
1466 LLVMTypeRef
*vreg_types
;
1467 MonoType
**vreg_cli_types
;
1468 int i
, max_block_num
, pindex
, bb_index
;
1469 int *pindexes
= NULL
;
1470 gboolean last
= FALSE
;
1471 GPtrArray
*phi_values
;
1472 LLVMCallInfo
*linfo
;
1474 LLVMModuleRef module
;
1476 gboolean
*unreachable
;
1478 GPtrArray
*bblock_list
;
1479 MonoMethodHeader
*header
;
1480 MonoExceptionClause
*clause
;
1482 /* The code below might acquire the loader lock, so use it for global locking */
1483 mono_loader_lock ();
1485 /* Used to communicate with the callbacks */
1486 TlsSetValue (current_cfg_tls_id
, cfg
);
1488 ctx
= g_new0 (EmitContext
, 1);
1490 ctx
->mempool
= cfg
->mempool
;
1493 * This maps vregs to the LLVM instruction defining them
1495 values
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
1497 * This maps vregs for volatile variables to the LLVM instruction defining their
1500 addresses
= g_new0 (LLVMValueRef
, cfg
->next_vreg
);
1501 vreg_types
= g_new0 (LLVMTypeRef
, cfg
->next_vreg
);
1502 vreg_cli_types
= g_new0 (MonoType
*, cfg
->next_vreg
);
1503 phi_values
= g_ptr_array_new ();
1505 * This signals whenever the vreg was defined by a phi node with no input vars
1506 * (i.e. all its input bblocks end with NOT_REACHABLE).
1508 is_dead
= g_new0 (gboolean
, cfg
->next_vreg
);
1509 /* Whenever the bblock is unreachable */
1510 unreachable
= g_new0 (gboolean
, cfg
->max_block_num
);
1512 bblock_list
= g_ptr_array_new ();
1514 ctx
->values
= values
;
1515 ctx
->addresses
= addresses
;
1516 ctx
->vreg_cli_types
= vreg_cli_types
;
1517 ctx
->region_to_handler
= g_hash_table_new (NULL
, NULL
);
1519 if (cfg
->compile_aot
) {
1520 ctx
->lmodule
= &aot_module
;
1521 method_name
= mono_aot_get_method_name (cfg
);
1522 debug_name
= mono_aot_get_method_debug_name (cfg
);
1525 ctx
->lmodule
= &jit_module
;
1526 method_name
= mono_method_full_name (cfg
->method
, TRUE
);
1530 module
= ctx
->module
= ctx
->lmodule
->module
;
1534 static int count
= 0;
1537 if (getenv ("LLVM_COUNT")) {
1538 if (count
== atoi (getenv ("LLVM_COUNT"))) {
1539 printf ("LAST: %s\n", mono_method_full_name (cfg
->method
, TRUE
));
1542 if (count
> atoi (getenv ("LLVM_COUNT")))
1543 LLVM_FAILURE (ctx
, "");
1548 sig
= mono_method_signature (cfg
->method
);
1551 linfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
1553 CHECK_FAILURE (ctx
);
1555 if (cfg
->rgctx_var
) {
1556 if (IS_LLVM_MONO_BRANCH
)
1557 linfo
->rgctx_arg
= TRUE
;
1559 LLVM_FAILURE (ctx
, "rgctx arg");
1561 method_type
= sig_to_llvm_sig (ctx
, sig
, linfo
);
1562 CHECK_FAILURE (ctx
);
1564 method
= LLVMAddFunction (module
, method_name
, method_type
);
1565 ctx
->lmethod
= method
;
1567 if (linfo
->rgctx_arg
)
1568 LLVMSetFunctionCallConv (method
, LLVMMono1CallConv
);
1569 LLVMSetLinkage (method
, LLVMPrivateLinkage
);
1571 if (cfg
->method
->save_lmf
)
1572 LLVM_FAILURE (ctx
, "lmf");
1575 LLVM_FAILURE (ctx
, "pinvoke signature");
1577 header
= cfg
->header
;
1578 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1579 clause
= &header
->clauses
[i
];
1580 if (clause
->flags
!= MONO_EXCEPTION_CLAUSE_FINALLY
&& clause
->flags
!= MONO_EXCEPTION_CLAUSE_NONE
)
1581 LLVM_FAILURE (ctx
, "non-finally/catch clause.");
1585 * This maps parameter indexes in the original signature to the indexes in
1586 * the LLVM signature.
1588 pindexes
= g_new0 (int, sig
->param_count
);
1590 if (linfo
->rgctx_arg
) {
1591 ctx
->rgctx_arg
= LLVMGetParam (method
, pindex
);
1593 * We mark the rgctx parameter with the inreg attribute, which is mapped to
1594 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
1595 * CC_X86_64_Mono in X86CallingConv.td.
1597 LLVMAddAttribute (ctx
->rgctx_arg
, LLVMInRegAttribute
);
1600 if (cfg
->vret_addr
) {
1601 values
[cfg
->vret_addr
->dreg
] = LLVMGetParam (method
, pindex
);
1605 values
[cfg
->args
[0]->dreg
] = LLVMGetParam (method
, pindex
);
1608 for (i
= 0; i
< sig
->param_count
; ++i
) {
1609 values
[cfg
->args
[i
+ sig
->hasthis
]->dreg
] = LLVMGetParam (method
, pindex
);
1610 pindexes
[i
] = pindex
;
1611 if (linfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeInReg
) {
1612 if (linfo
->args
[i
+ sig
->hasthis
].pair_storage
[0] != LLVMArgNone
)
1614 if (linfo
->args
[i
+ sig
->hasthis
].pair_storage
[1] != LLVMArgNone
)
1616 } else if (linfo
->args
[i
+ sig
->hasthis
].storage
== LLVMArgVtypeByVal
) {
1617 LLVMAddAttribute (LLVMGetParam (method
, pindex
), LLVMByValAttribute
);
1625 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
)
1626 max_block_num
= MAX (max_block_num
, bb
->block_num
);
1627 ctx
->bblocks
= bblocks
= g_new0 (BBInfo
, max_block_num
+ 1);
1629 /* Add branches between non-consecutive bblocks */
1630 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1631 if (bb
->last_ins
&& MONO_IS_COND_BRANCH_OP (bb
->last_ins
) &&
1632 bb
->next_bb
!= bb
->last_ins
->inst_false_bb
) {
1634 MonoInst
*inst
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (MonoInst
));
1635 inst
->opcode
= OP_BR
;
1636 inst
->inst_target_bb
= bb
->last_ins
->inst_false_bb
;
1637 mono_bblock_add_inst (bb
, inst
);
1642 * Make a first pass over the code to precreate PHI nodes.
1644 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1646 LLVMBuilderRef builder
;
1648 char dname_buf
[128];
1650 builder
= create_builder (ctx
);
1652 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
1653 switch (ins
->opcode
) {
1658 LLVMTypeRef phi_type
= llvm_type_to_stack_type (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
1660 CHECK_FAILURE (ctx
);
1662 if (ins
->opcode
== OP_VPHI
) {
1663 /* Treat valuetype PHI nodes as operating on the address itself */
1664 g_assert (ins
->klass
);
1665 phi_type
= LLVMPointerType (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
), 0);
1669 * Have to precreate these, as they can be referenced by
1670 * earlier instructions.
1672 sprintf (dname_buf
, "t%d", ins
->dreg
);
1674 values
[ins
->dreg
] = LLVMBuildPhi (builder
, phi_type
, dname
);
1676 if (ins
->opcode
== OP_VPHI
)
1677 addresses
[ins
->dreg
] = values
[ins
->dreg
];
1679 g_ptr_array_add (phi_values
, values
[ins
->dreg
]);
1682 * Set the expected type of the incoming arguments since these have
1683 * to have the same type.
1685 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
1686 int sreg1
= ins
->inst_phi_args
[i
+ 1];
1689 vreg_types
[sreg1
] = phi_type
;
1700 * Create an ordering for bblocks, use the depth first order first, then
1701 * put the exception handling bblocks last.
1703 for (bb_index
= 0; bb_index
< cfg
->num_bblocks
; ++bb_index
) {
1704 bb
= cfg
->bblocks
[bb_index
];
1705 if (!(bb
->region
!= -1 && !MONO_BBLOCK_IS_IN_REGION (bb
, MONO_REGION_TRY
))) {
1706 g_ptr_array_add (bblock_list
, bb
);
1707 bblocks
[bb
->block_num
].added
= TRUE
;
1711 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
1712 if (!bblocks
[bb
->block_num
].added
)
1713 g_ptr_array_add (bblock_list
, bb
);
1717 * Second pass: generate code.
1719 for (bb_index
= 0; bb_index
< bblock_list
->len
; ++bb_index
) {
1721 LLVMBasicBlockRef cbb
;
1722 LLVMBuilderRef builder
;
1723 gboolean has_terminator
;
1725 LLVMValueRef lhs
, rhs
;
1727 bb
= g_ptr_array_index (bblock_list
, bb_index
);
1729 if (!(bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
1732 cbb
= get_bb (ctx
, bb
);
1733 builder
= create_builder (ctx
);
1734 ctx
->builder
= builder
;
1735 LLVMPositionBuilderAtEnd (builder
, cbb
);
1737 if (bb
== cfg
->bb_entry
)
1738 emit_entry_bb (ctx
, builder
, pindexes
);
1739 CHECK_FAILURE (ctx
);
1741 if (bb
->flags
& BB_EXCEPTION_HANDLER
) {
1743 LLVMValueRef eh_selector
, eh_exception
, personality
, args
[4];
1745 static gint32 mapping_inited
;
1746 static int ti_generator
;
1749 LLVMValueRef type_info
;
1752 if (!bblocks
[bb
->block_num
].invoke_target
) {
1754 * LLVM asserts if llvm.eh.selector is called from a bblock which
1755 * doesn't have an invoke pointing at it.
1757 LLVM_FAILURE (ctx
, "handler without invokes");
1760 eh_selector
= LLVMGetNamedFunction (module
, eh_selector_name
);
1762 if (cfg
->compile_aot
) {
1763 /* Use a dummy personality function */
1764 personality
= LLVMGetNamedFunction (module
, "mono_aot_personality");
1765 g_assert (personality
);
1767 personality
= LLVMGetNamedFunction (module
, "mono_personality");
1768 if (InterlockedCompareExchange (&mapping_inited
, 1, 0) == 0)
1769 LLVMAddGlobalMapping (ee
, personality
, mono_personality
);
1772 i8ptr
= LLVMPointerType (LLVMInt8Type (), 0);
1774 clause_index
= (mono_get_block_region_notry (cfg
, bb
->region
) >> 8) - 1;
1777 * Create the type info
1779 sprintf (ti_name
, "type_info_%d", ti_generator
);
1782 if (cfg
->compile_aot
) {
1783 /* decode_eh_frame () in aot-runtime.c will decode this */
1784 type_info
= LLVMAddGlobal (module
, LLVMInt32Type (), ti_name
);
1785 LLVMSetInitializer (type_info
, LLVMConstInt (LLVMInt32Type (), clause_index
, FALSE
));
1787 LLVMSetLinkage (type_info
, LLVMPrivateLinkage
);
1788 LLVMSetVisibility (type_info
, LLVMHiddenVisibility
);
1791 * Enabling this causes llc to crash:
1792 * http://llvm.org/bugs/show_bug.cgi?id=6102
1794 LLVM_FAILURE (ctx
, "aot+clauses");
1796 /* exception_cb will decode this */
1797 ti
= g_malloc (sizeof (gint32
));
1798 *(gint32
*)ti
= clause_index
;
1800 type_info
= LLVMAddGlobal (module
, i8ptr
, ti_name
);
1802 LLVMAddGlobalMapping (ee
, type_info
, ti
);
1805 args
[0] = LLVMConstNull (i8ptr
);
1806 args
[1] = LLVMConstBitCast (personality
, i8ptr
);
1807 args
[2] = type_info
;
1808 LLVMBuildCall (builder
, eh_selector
, args
, 3, "");
1810 /* Store the exception into the exvar */
1811 if (bb
->in_scount
== 1) {
1812 g_assert (bb
->in_scount
== 1);
1813 exvar
= bb
->in_stack
[0];
1815 eh_exception
= LLVMGetNamedFunction (module
, "llvm.eh.exception");
1817 // FIXME: This is shared with filter clauses ?
1818 g_assert (!values
[exvar
->dreg
]);
1819 values
[exvar
->dreg
] = LLVMBuildCall (builder
, eh_exception
, NULL
, 0, "");
1820 emit_volatile_store (ctx
, exvar
->dreg
);
1824 has_terminator
= FALSE
;
1825 for (ins
= bb
->code
; ins
; ins
= ins
->next
) {
1826 const char *spec
= LLVM_INS_INFO (ins
->opcode
);
1828 char dname_buf
[128];
1831 /* There could be instructions after a terminator, skip them */
1834 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
)) {
1835 sprintf (dname_buf
, "t%d", ins
->dreg
);
1839 if (spec
[MONO_INST_SRC1
] != ' ' && spec
[MONO_INST_SRC1
] != 'v') {
1840 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg1
);
1842 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1843 lhs
= emit_volatile_load (ctx
, ins
->sreg1
);
1845 /* It is ok for SETRET to have an uninitialized argument */
1846 if (!values
[ins
->sreg1
] && ins
->opcode
!= OP_SETRET
)
1847 LLVM_FAILURE (ctx
, "sreg1");
1848 lhs
= values
[ins
->sreg1
];
1854 if (spec
[MONO_INST_SRC2
] != ' ' && spec
[MONO_INST_SRC2
] != ' ') {
1855 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->sreg2
);
1856 if (var
&& var
->flags
& (MONO_INST_VOLATILE
|MONO_INST_INDIRECT
)) {
1857 rhs
= emit_volatile_load (ctx
, ins
->sreg2
);
1859 if (!values
[ins
->sreg2
])
1860 LLVM_FAILURE (ctx
, "sreg2");
1861 rhs
= values
[ins
->sreg2
];
1867 //mono_print_ins (ins);
1868 switch (ins
->opcode
) {
1871 case OP_LIVERANGE_START
:
1872 case OP_LIVERANGE_END
:
1875 values
[ins
->dreg
] = LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
);
1878 #if SIZEOF_VOID_P == 4
1879 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
1881 values
[ins
->dreg
] = LLVMConstInt (LLVMInt64Type (), (gint64
)ins
->inst_c0
, FALSE
);
1885 values
[ins
->dreg
] = LLVMConstReal (LLVMDoubleType (), *(double*)ins
->inst_p0
);
1888 values
[ins
->dreg
] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins
->inst_p0
), LLVMDoubleType ());
1891 LLVMBuildBr (builder
, get_bb (ctx
, ins
->inst_target_bb
));
1892 has_terminator
= TRUE
;
1898 LLVMBasicBlockRef new_bb
;
1899 LLVMBuilderRef new_builder
;
1901 // The default branch is already handled
1902 // FIXME: Handle it here
1904 /* Start new bblock */
1905 sprintf (bb_name
, "SWITCH_DEFAULT_BB%d", ctx
->default_index
++);
1906 new_bb
= LLVMAppendBasicBlock (ctx
->lmethod
, bb_name
);
1908 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
1909 v
= LLVMBuildSwitch (builder
, lhs
, new_bb
, GPOINTER_TO_UINT (ins
->klass
));
1910 for (i
= 0; i
< GPOINTER_TO_UINT (ins
->klass
); ++i
) {
1911 MonoBasicBlock
*target_bb
= ins
->inst_many_bb
[i
];
1913 LLVMAddCase (v
, LLVMConstInt (LLVMInt32Type (), i
, FALSE
), get_bb (ctx
, target_bb
));
1916 new_builder
= create_builder (ctx
);
1917 LLVMPositionBuilderAtEnd (new_builder
, new_bb
);
1918 LLVMBuildUnreachable (new_builder
);
1920 has_terminator
= TRUE
;
1921 g_assert (!ins
->next
);
1927 if (linfo
->ret
.storage
== LLVMArgVtypeInReg
) {
1928 LLVMTypeRef ret_type
= LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method
)));
1929 LLVMValueRef part1
, retval
;
1932 size
= get_vtype_size (sig
->ret
);
1934 g_assert (addresses
[ins
->sreg1
]);
1936 g_assert (linfo
->ret
.pair_storage
[0] == LLVMArgInIReg
);
1937 g_assert (linfo
->ret
.pair_storage
[1] == LLVMArgNone
);
1939 part1
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMIntType (size
* 8), 0), ""), ""), IntPtrType ());
1941 retval
= LLVMBuildInsertValue (builder
, LLVMGetUndef (ret_type
), part1
, 0, "");
1943 LLVMBuildRet (builder
, retval
);
1947 if (linfo
->ret
.storage
== LLVMArgVtypeRetAddr
) {
1948 LLVMBuildRetVoid (builder
);
1952 if (!lhs
|| is_dead
[ins
->sreg1
]) {
1954 * The method did not set its return value, probably because it
1955 * ends with a throw.
1958 LLVMBuildRetVoid (builder
);
1960 LLVMBuildRet (builder
, LLVMConstNull (type_to_llvm_type (ctx
, sig
->ret
)));
1962 LLVMBuildRet (builder
, convert (ctx
, lhs
, type_to_llvm_type (ctx
, sig
->ret
)));
1964 has_terminator
= TRUE
;
1970 case OP_ICOMPARE_IMM
:
1971 case OP_LCOMPARE_IMM
:
1972 case OP_COMPARE_IMM
:
1974 case OP_AMD64_ICOMPARE_MEMBASE_REG
:
1975 case OP_AMD64_ICOMPARE_MEMBASE_IMM
:
1978 case OP_X86_COMPARE_MEMBASE_REG
:
1979 case OP_X86_COMPARE_MEMBASE_IMM
:
1985 if (ins
->next
->opcode
== OP_NOP
)
1988 if (ins
->next
->opcode
== OP_BR
)
1989 /* The comparison result is not needed */
1992 rel
= mono_opcode_to_cond (ins
->next
->opcode
);
1994 /* Used for implementing bound checks */
1996 if ((ins
->opcode
== OP_AMD64_ICOMPARE_MEMBASE_REG
) || (ins
->opcode
== OP_AMD64_ICOMPARE_MEMBASE_IMM
)) {
2001 t
= LLVMInt32Type ();
2003 g_assert (ins
->inst_offset
% size
== 0);
2004 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2006 lhs
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (t
, 0)), &index
, 1, ""), "");
2008 if (ins
->opcode
== OP_AMD64_ICOMPARE_MEMBASE_IMM
) {
2009 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2010 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2012 if (ins
->opcode
== OP_AMD64_ICOMPARE_MEMBASE_REG
)
2013 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2017 if ((ins
->opcode
== OP_X86_COMPARE_MEMBASE_REG
) || (ins
->opcode
== OP_X86_COMPARE_MEMBASE_IMM
)) {
2022 t
= LLVMInt32Type ();
2024 g_assert (ins
->inst_offset
% size
== 0);
2025 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2027 lhs
= LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (t
, 0)), &index
, 1, ""), "");
2029 if (ins
->opcode
== OP_X86_COMPARE_MEMBASE_IMM
) {
2030 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2031 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2033 if (ins
->opcode
== OP_X86_COMPARE_MEMBASE_REG
)
2034 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2037 if (ins
->opcode
== OP_ICOMPARE_IMM
) {
2038 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2039 rhs
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2041 if (ins
->opcode
== OP_LCOMPARE_IMM
) {
2042 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2043 rhs
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2045 if (ins
->opcode
== OP_LCOMPARE
) {
2046 lhs
= convert (ctx
, lhs
, LLVMInt64Type ());
2047 rhs
= convert (ctx
, rhs
, LLVMInt64Type ());
2049 if (ins
->opcode
== OP_ICOMPARE
) {
2050 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2051 rhs
= convert (ctx
, rhs
, LLVMInt32Type ());
2055 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2056 rhs
= convert (ctx
, rhs
, LLVMTypeOf (lhs
));
2057 else if (LLVMGetTypeKind (LLVMTypeOf (rhs
)) == LLVMPointerTypeKind
)
2058 lhs
= convert (ctx
, lhs
, LLVMTypeOf (rhs
));
2061 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2062 if (ins
->opcode
== OP_FCOMPARE
)
2063 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2064 else if (ins
->opcode
== OP_COMPARE_IMM
)
2065 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), "");
2066 else if (ins
->opcode
== OP_COMPARE
)
2067 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], convert (ctx
, lhs
, IntPtrType ()), convert (ctx
, rhs
, IntPtrType ()), "");
2069 cmp
= LLVMBuildICmp (builder
, cond_to_llvm_cond
[rel
], lhs
, rhs
, "");
2071 if (MONO_IS_COND_BRANCH_OP (ins
->next
)) {
2072 LLVMBuildCondBr (builder
, cmp
, get_bb (ctx
, ins
->next
->inst_true_bb
), get_bb (ctx
, ins
->next
->inst_false_bb
));
2073 has_terminator
= TRUE
;
2074 } else if (MONO_IS_SETCC (ins
->next
)) {
2075 sprintf (dname_buf
, "t%d", ins
->next
->dreg
);
2077 values
[ins
->next
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2079 /* Add stores for volatile variables */
2080 emit_volatile_store (ctx
, ins
->next
->dreg
);
2081 } else if (MONO_IS_COND_EXC (ins
->next
)) {
2082 //emit_cond_throw_pos (ctx);
2083 emit_cond_system_exception (ctx
, bb
, ins
->next
->inst_p1
, cmp
);
2084 CHECK_FAILURE (ctx
);
2085 builder
= ctx
->builder
;
2087 LLVM_FAILURE (ctx
, "next");
2101 rel
= mono_opcode_to_cond (ins
->opcode
);
2103 cmp
= LLVMBuildFCmp (builder
, fpcond_to_llvm_cond
[rel
], convert (ctx
, lhs
, LLVMDoubleType ()), convert (ctx
, rhs
, LLVMDoubleType ()), "");
2104 values
[ins
->dreg
] = LLVMBuildZExt (builder
, cmp
, LLVMInt32Type (), dname
);
2112 gboolean empty
= TRUE
;
2114 /* Check that all input bblocks really branch to us */
2115 for (i
= 0; i
< bb
->in_count
; ++i
) {
2116 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_NOT_REACHED
)
2117 ins
->inst_phi_args
[i
+ 1] = -1;
2123 /* LLVM doesn't like phi instructions with zero operands */
2124 is_dead
[ins
->dreg
] = TRUE
;
2128 /* Created earlier, insert it now */
2129 LLVMInsertIntoBuilder (builder
, values
[ins
->dreg
]);
2131 for (i
= 0; i
< ins
->inst_phi_args
[0]; i
++) {
2132 int sreg1
= ins
->inst_phi_args
[i
+ 1];
2136 * Count the number of times the incoming bblock branches to us,
2137 * since llvm requires a separate entry for each.
2139 if (bb
->in_bb
[i
]->last_ins
&& bb
->in_bb
[i
]->last_ins
->opcode
== OP_SWITCH
) {
2140 MonoInst
*switch_ins
= bb
->in_bb
[i
]->last_ins
;
2143 for (j
= 0; j
< GPOINTER_TO_UINT (switch_ins
->klass
); ++j
) {
2144 if (switch_ins
->inst_many_bb
[j
] == bb
)
2151 /* Remember for later */
2152 for (j
= 0; j
< count
; ++j
) {
2153 PhiNode
*node
= mono_mempool_alloc0 (ctx
->mempool
, sizeof (PhiNode
));
2156 node
->in_bb
= bb
->in_bb
[i
];
2158 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
);
2167 values
[ins
->dreg
] = lhs
;
2170 MonoInst
*var
= get_vreg_to_inst (cfg
, ins
->dreg
);
2173 values
[ins
->dreg
] = lhs
;
2175 if (var
&& var
->klass
->byval_arg
.type
== MONO_TYPE_R4
) {
2177 * This is added by the spilling pass in case of the JIT,
2178 * but we have to do it ourselves.
2180 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], LLVMFloatType ());
2214 lhs
= convert (ctx
, lhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2215 rhs
= convert (ctx
, rhs
, regtype_to_llvm_type (spec
[MONO_INST_DEST
]));
2217 switch (ins
->opcode
) {
2220 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, dname
);
2224 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, dname
);
2228 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, rhs
, dname
);
2232 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, rhs
, dname
);
2236 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, rhs
, dname
);
2240 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, rhs
, dname
);
2244 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, rhs
, dname
);
2247 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, dname
);
2251 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, dname
);
2255 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, dname
);
2259 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, dname
);
2263 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, rhs
, dname
);
2267 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, rhs
, dname
);
2271 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, rhs
, dname
);
2275 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, dname
);
2278 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, dname
);
2281 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, dname
);
2285 g_assert_not_reached ();
2292 case OP_IREM_UN_IMM
:
2294 case OP_IDIV_UN_IMM
:
2300 case OP_ISHR_UN_IMM
:
2309 case OP_LSHR_UN_IMM
:
2317 if (spec
[MONO_INST_SRC1
] == 'l') {
2318 imm
= LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins
), FALSE
);
2320 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2323 #if SIZEOF_VOID_P == 4
2324 if (ins
->opcode
== OP_LSHL_IMM
|| ins
->opcode
== OP_LSHR_IMM
|| ins
->opcode
== OP_LSHR_UN_IMM
)
2325 imm
= LLVMConstInt (LLVMInt32Type (), ins
->inst_imm
, FALSE
);
2328 if (LLVMGetTypeKind (LLVMTypeOf (lhs
)) == LLVMPointerTypeKind
)
2329 lhs
= convert (ctx
, lhs
, IntPtrType ());
2330 imm
= convert (ctx
, imm
, LLVMTypeOf (lhs
));
2331 switch (ins
->opcode
) {
2335 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, imm
, dname
);
2339 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, imm
, dname
);
2343 values
[ins
->dreg
] = LLVMBuildMul (builder
, lhs
, imm
, dname
);
2347 values
[ins
->dreg
] = LLVMBuildSDiv (builder
, lhs
, imm
, dname
);
2349 case OP_IDIV_UN_IMM
:
2350 case OP_LDIV_UN_IMM
:
2351 values
[ins
->dreg
] = LLVMBuildUDiv (builder
, lhs
, imm
, dname
);
2355 values
[ins
->dreg
] = LLVMBuildSRem (builder
, lhs
, imm
, dname
);
2357 case OP_IREM_UN_IMM
:
2358 values
[ins
->dreg
] = LLVMBuildURem (builder
, lhs
, imm
, dname
);
2363 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, imm
, dname
);
2367 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, imm
, dname
);
2371 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, imm
, dname
);
2376 values
[ins
->dreg
] = LLVMBuildShl (builder
, lhs
, imm
, dname
);
2381 values
[ins
->dreg
] = LLVMBuildAShr (builder
, lhs
, imm
, dname
);
2383 case OP_ISHR_UN_IMM
:
2384 /* This is used to implement conv.u4, so the lhs could be an i8 */
2385 lhs
= convert (ctx
, lhs
, LLVMInt32Type ());
2386 imm
= convert (ctx
, imm
, LLVMInt32Type ());
2387 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2389 case OP_LSHR_UN_IMM
:
2390 values
[ins
->dreg
] = LLVMBuildLShr (builder
, lhs
, imm
, dname
);
2393 g_assert_not_reached ();
2398 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), convert (ctx
, lhs
, LLVMInt32Type ()), dname
);
2401 values
[ins
->dreg
] = LLVMBuildSub (builder
, LLVMConstInt (LLVMInt64Type (), 0, FALSE
), lhs
, dname
);
2404 lhs
= convert (ctx
, lhs
, LLVMDoubleType ());
2405 values
[ins
->dreg
] = LLVMBuildFSub (builder
, LLVMConstReal (LLVMDoubleType (), 0.0), lhs
, dname
);
2408 guint32 v
= 0xffffffff;
2409 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt32Type (), v
, FALSE
), lhs
, dname
);
2413 guint64 v
= 0xffffffffffffffffLL
;
2414 values
[ins
->dreg
] = LLVMBuildXor (builder
, LLVMConstInt (LLVMInt64Type (), v
, FALSE
), lhs
, dname
);
2417 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2419 LLVMValueRef v1
, v2
;
2421 v1
= LLVMBuildMul (builder
, convert (ctx
, rhs
, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins
->backend
.shift_amount
), FALSE
), "");
2422 v2
= LLVMBuildAdd (builder
, convert (ctx
, lhs
, IntPtrType ()), v1
, "");
2423 values
[ins
->dreg
] = LLVMBuildAdd (builder
, v2
, LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
), dname
);
2428 case OP_ICONV_TO_I1
:
2429 case OP_ICONV_TO_I2
:
2430 case OP_ICONV_TO_I4
:
2431 case OP_ICONV_TO_U1
:
2432 case OP_ICONV_TO_U2
:
2433 case OP_ICONV_TO_U4
:
2434 case OP_LCONV_TO_I1
:
2435 case OP_LCONV_TO_I2
:
2436 case OP_LCONV_TO_U1
:
2437 case OP_LCONV_TO_U2
:
2438 case OP_LCONV_TO_U4
: {
2441 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
);
2443 /* Have to do two casts since our vregs have type int */
2444 v
= LLVMBuildTrunc (builder
, lhs
, op_to_llvm_type (ins
->opcode
), "");
2446 values
[ins
->dreg
] = LLVMBuildSExt (builder
, v
, LLVMInt32Type (), dname
);
2448 values
[ins
->dreg
] = LLVMBuildZExt (builder
, v
, LLVMInt32Type (), dname
);
2451 case OP_ICONV_TO_I8
:
2452 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2454 case OP_ICONV_TO_U8
:
2455 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2457 case OP_FCONV_TO_I4
:
2458 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt32Type (), dname
);
2460 case OP_FCONV_TO_I1
:
2461 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2463 case OP_FCONV_TO_U1
:
2464 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt8Type (), dname
), LLVMInt32Type (), "");
2466 case OP_FCONV_TO_I2
:
2467 values
[ins
->dreg
] = LLVMBuildSExt (builder
, LLVMBuildFPToSI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2469 case OP_FCONV_TO_U2
:
2470 values
[ins
->dreg
] = LLVMBuildZExt (builder
, LLVMBuildFPToUI (builder
, lhs
, LLVMInt16Type (), dname
), LLVMInt32Type (), "");
2472 case OP_FCONV_TO_I8
:
2473 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, LLVMInt64Type (), dname
);
2476 values
[ins
->dreg
] = LLVMBuildFPToSI (builder
, lhs
, IntPtrType (), dname
);
2478 case OP_ICONV_TO_R8
:
2479 case OP_LCONV_TO_R8
:
2480 values
[ins
->dreg
] = LLVMBuildSIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2482 case OP_LCONV_TO_R_UN
:
2483 values
[ins
->dreg
] = LLVMBuildUIToFP (builder
, lhs
, LLVMDoubleType (), dname
);
2485 #if SIZEOF_VOID_P == 4
2488 case OP_LCONV_TO_I4
:
2489 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2491 case OP_ICONV_TO_R4
:
2492 case OP_LCONV_TO_R4
:
2493 v
= LLVMBuildSIToFP (builder
, lhs
, LLVMFloatType (), "");
2494 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2496 case OP_FCONV_TO_R4
:
2497 v
= LLVMBuildFPTrunc (builder
, lhs
, LLVMFloatType (), "");
2498 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, v
, LLVMDoubleType (), dname
);
2501 values
[ins
->dreg
] = LLVMBuildSExt (builder
, lhs
, LLVMInt64Type (), dname
);
2504 values
[ins
->dreg
] = LLVMBuildZExt (builder
, lhs
, LLVMInt64Type (), dname
);
2507 values
[ins
->dreg
] = LLVMBuildTrunc (builder
, lhs
, LLVMInt32Type (), dname
);
2509 case OP_LOCALLOC_IMM
: {
2512 guint32 size
= ins
->inst_imm
;
2513 size
= (size
+ (MONO_ARCH_FRAME_ALIGNMENT
- 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1);
2515 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size
, FALSE
), MONO_ARCH_FRAME_ALIGNMENT
, "");
2517 if (ins
->flags
& MONO_INST_INIT
) {
2518 LLVMValueRef args
[5];
2521 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2522 args
[2] = LLVMConstInt (LLVMInt32Type (), size
, FALSE
);
2523 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2524 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2525 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2528 values
[ins
->dreg
] = v
;
2532 LLVMValueRef v
, size
;
2534 size
= LLVMBuildAnd (builder
, LLVMBuildAdd (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
- 1, FALSE
), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT
- 1), FALSE
), "");
2536 v
= mono_llvm_build_alloca (builder
, LLVMInt8Type (), size
, MONO_ARCH_FRAME_ALIGNMENT
, "");
2538 if (ins
->flags
& MONO_INST_INIT
) {
2539 LLVMValueRef args
[5];
2542 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
2544 args
[3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT
, FALSE
);
2545 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
2546 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
2548 values
[ins
->dreg
] = v
;
2552 case OP_LOADI1_MEMBASE
:
2553 case OP_LOADU1_MEMBASE
:
2554 case OP_LOADI2_MEMBASE
:
2555 case OP_LOADU2_MEMBASE
:
2556 case OP_LOADI4_MEMBASE
:
2557 case OP_LOADU4_MEMBASE
:
2558 case OP_LOADI8_MEMBASE
:
2559 case OP_LOADR4_MEMBASE
:
2560 case OP_LOADR8_MEMBASE
:
2561 case OP_LOAD_MEMBASE
:
2569 LLVMValueRef index
, addr
;
2571 gboolean sext
= FALSE
, zext
= FALSE
;
2572 gboolean is_volatile
= (ins
->flags
& MONO_INST_FAULT
);
2574 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2580 * We emit volatile loads for loads which can fault, because otherwise
2581 * LLVM will generate invalid code when encountering a load from a
2584 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
)) {
2585 addr
= LLVMConstInt (IntPtrType (), ins
->inst_imm
, FALSE
);
2586 } else if (ins
->inst_offset
== 0) {
2587 addr
= values
[ins
->inst_basereg
];
2588 } else if (ins
->inst_offset
% size
!= 0) {
2589 /* Unaligned load */
2590 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2591 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
2593 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2594 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
2597 addr
= convert (ctx
, addr
, LLVMPointerType (t
, 0));
2599 values
[ins
->dreg
] = mono_llvm_build_load (builder
, addr
, dname
, is_volatile
);
2602 values
[ins
->dreg
] = LLVMBuildSExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
2604 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), dname
);
2605 else if (ins
->opcode
== OP_LOADR4_MEMBASE
)
2606 values
[ins
->dreg
] = LLVMBuildFPExt (builder
, values
[ins
->dreg
], LLVMDoubleType (), dname
);
2610 case OP_STOREI1_MEMBASE_REG
:
2611 case OP_STOREI2_MEMBASE_REG
:
2612 case OP_STOREI4_MEMBASE_REG
:
2613 case OP_STOREI8_MEMBASE_REG
:
2614 case OP_STORER4_MEMBASE_REG
:
2615 case OP_STORER8_MEMBASE_REG
:
2616 case OP_STORE_MEMBASE_REG
: {
2618 LLVMValueRef index
, addr
;
2620 gboolean sext
= FALSE
, zext
= FALSE
;
2622 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2624 if (ins
->inst_offset
% size
!= 0) {
2625 /* Unaligned store */
2626 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2627 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
2629 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2630 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
2632 LLVMBuildStore (builder
, convert (ctx
, values
[ins
->sreg1
], t
), convert (ctx
, addr
, LLVMPointerType (t
, 0)));
2636 case OP_STOREI1_MEMBASE_IMM
:
2637 case OP_STOREI2_MEMBASE_IMM
:
2638 case OP_STOREI4_MEMBASE_IMM
:
2639 case OP_STOREI8_MEMBASE_IMM
:
2640 case OP_STORE_MEMBASE_IMM
: {
2642 LLVMValueRef index
, addr
;
2644 gboolean sext
= FALSE
, zext
= FALSE
;
2646 t
= load_store_to_llvm_type (ins
->opcode
, &size
, &sext
, &zext
);
2648 if (ins
->inst_offset
% size
!= 0) {
2649 /* Unaligned store */
2650 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
, FALSE
);
2651 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (LLVMInt8Type (), 0)), &index
, 1, "");
2653 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2654 addr
= LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], LLVMPointerType (t
, 0)), &index
, 1, "");
2656 LLVMBuildStore (builder
, convert (ctx
, LLVMConstInt (t
, ins
->inst_imm
, FALSE
), t
), addr
);
2661 mono_llvm_build_load (builder
, convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (IntPtrType (), 0)), "", TRUE
);
2663 case OP_OUTARG_VTRETADDR
:
2670 case OP_VOIDCALL_MEMBASE
:
2671 case OP_CALL_MEMBASE
:
2672 case OP_LCALL_MEMBASE
:
2673 case OP_FCALL_MEMBASE
:
2674 case OP_VCALL_MEMBASE
:
2675 case OP_VOIDCALL_REG
:
2679 case OP_VCALL_REG
: {
2680 MonoCallInst
*call
= (MonoCallInst
*)ins
;
2681 MonoMethodSignature
*sig
= call
->signature
;
2682 LLVMValueRef callee
, lcall
;
2684 LLVMCallInfo
*cinfo
;
2688 LLVMTypeRef llvm_sig
;
2691 gboolean
virtual, calli
;
2693 if (call
->signature
->call_convention
!= MONO_CALL_DEFAULT
)
2694 LLVM_FAILURE (ctx
, "non-default callconv");
2696 if (call
->rgctx_arg_reg
&& !IS_LLVM_MONO_BRANCH
)
2697 LLVM_FAILURE (ctx
, "rgctx reg in call");
2699 cinfo
= call
->cinfo
;
2700 if (call
->rgctx_arg_reg
)
2701 cinfo
->rgctx_arg
= TRUE
;
2702 if (call
->imt_arg_reg
)
2703 cinfo
->imt_arg
= TRUE
;
2705 vretaddr
= cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeRetAddr
;
2707 llvm_sig
= sig_to_llvm_sig (ctx
, sig
, cinfo
);
2708 CHECK_FAILURE (ctx
);
2710 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
);
2711 calli
= (ins
->opcode
== OP_VOIDCALL_REG
|| ins
->opcode
== OP_CALL_REG
|| ins
->opcode
== OP_VCALL_REG
|| ins
->opcode
== OP_LCALL_REG
|| ins
->opcode
== OP_FCALL_REG
);
2713 /* FIXME: Avoid creating duplicate methods */
2715 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
2719 if (cfg
->compile_aot
) {
2720 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_METHOD
, call
->method
);
2722 LLVM_FAILURE (ctx
, "can't encode patch");
2724 callee
= LLVMAddFunction (module
, "", llvm_sig
);
2727 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2729 LLVMAddGlobalMapping (ee
, callee
, target
);
2734 MonoJitICallInfo
*info
= mono_find_jit_icall_by_addr (call
->fptr
);
2740 memset (&ji, 0, sizeof (ji));
2741 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2742 ji.data.target = info->name;
2744 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2746 if (cfg
->compile_aot
) {
2747 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_INTERNAL_METHOD
, (char*)info
->name
);
2749 LLVM_FAILURE (ctx
, "can't encode patch");
2751 callee
= LLVMAddFunction (module
, "", llvm_sig
);
2752 target
= (gpointer
)mono_icall_get_wrapper (info
);
2753 LLVMAddGlobalMapping (ee
, callee
, target
);
2756 if (cfg
->compile_aot
) {
2758 if (cfg
->abs_patches
) {
2759 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
2761 callee
= get_plt_entry (ctx
, llvm_sig
, abs_ji
->type
, abs_ji
->data
.target
);
2763 LLVM_FAILURE (ctx
, "can't encode patch");
2767 LLVM_FAILURE (ctx
, "aot");
2769 callee
= LLVMAddFunction (module
, "", llvm_sig
);
2771 if (cfg
->abs_patches
) {
2772 MonoJumpInfo
*abs_ji
= g_hash_table_lookup (cfg
->abs_patches
, call
->fptr
);
2775 * The monitor entry/exit trampolines might have
2776 * their own calling convention on some platforms.
2778 #ifndef TARGET_AMD64
2779 if (abs_ji
->type
== MONO_PATCH_INFO_MONITOR_ENTER
|| abs_ji
->type
== MONO_PATCH_INFO_MONITOR_EXIT
)
2780 LLVM_FAILURE (ctx
, "monitor enter/exit");
2782 target
= mono_resolve_patch_target (cfg
->method
, cfg
->domain
, NULL
, abs_ji
, FALSE
);
2783 LLVMAddGlobalMapping (ee
, callee
, target
);
2787 LLVMAddGlobalMapping (ee
, callee
, (gpointer
)call
->fptr
);
2793 int size
= sizeof (gpointer
);
2796 g_assert (ins
->inst_offset
% size
== 0);
2797 index
= LLVMConstInt (LLVMInt32Type (), ins
->inst_offset
/ size
, FALSE
);
2799 // FIXME: mono_arch_get_vcall_slot () can't decode the code
2800 // generated by LLVM
2801 //LLVM_FAILURE (ctx, "virtual call");
2804 * When using the llvm mono branch, we can support IMT directly, otherwise
2805 * we need to call a trampoline.
2807 if (call
->method
&& call
->method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
&& !IS_LLVM_MONO_BRANCH
) {
2808 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
2809 if (cfg
->compile_aot
) {
2810 MonoJumpInfoImtTramp
*imt_tramp
= g_new0 (MonoJumpInfoImtTramp
, 1);
2811 imt_tramp
->method
= call
->method
;
2812 imt_tramp
->vt_offset
= call
->inst
.inst_offset
;
2814 callee
= get_plt_entry (ctx
, llvm_sig
, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE
, imt_tramp
);
2816 callee
= LLVMAddFunction (module
, "", llvm_sig
);
2817 target
= mono_create_llvm_imt_trampoline (cfg
->domain
, call
->method
, call
->inst
.inst_offset
);
2818 LLVMAddGlobalMapping (ee
, callee
, target
);
2821 /* No support for passing the IMT argument */
2822 LLVM_FAILURE (ctx
, "imt");
2825 callee
= convert (ctx
, LLVMBuildLoad (builder
, LLVMBuildGEP (builder
, convert (ctx
, values
[ins
->inst_basereg
], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index
, 1, ""), ""), LLVMPointerType (llvm_sig
, 0));
2828 callee
= convert (ctx
, values
[ins
->sreg1
], LLVMPointerType (llvm_sig
, 0));
2830 if (ins
->flags
& MONO_INST_HAS_METHOD
) {
2835 * Collect and convert arguments
2837 pindexes
= mono_mempool_alloc0 (cfg
->mempool
, (sig
->param_count
+ 2) * sizeof (guint32
));
2838 args
= alloca (sizeof (LLVMValueRef
) * ((sig
->param_count
* 2) + sig
->hasthis
+ vretaddr
+ call
->rgctx_reg
));
2839 l
= call
->out_ireg_args
;
2842 if (IS_LLVM_MONO_BRANCH
) {
2843 if (call
->rgctx_arg_reg
)
2844 args
[pindex
++] = values
[call
->rgctx_arg_reg
];
2845 if (call
->imt_arg_reg
)
2846 args
[pindex
++] = values
[call
->imt_arg_reg
];
2850 if (!addresses
[call
->inst
.dreg
])
2851 addresses
[call
->inst
.dreg
] = build_alloca (ctx
, sig
->ret
);
2852 args
[pindex
++] = LLVMBuildPtrToInt (builder
, addresses
[call
->inst
.dreg
], IntPtrType (), "");
2855 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
2858 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
] : NULL
;
2860 regpair
= (guint32
)(gssize
)(l
->data
);
2861 reg
= regpair
& 0xffffff;
2862 args
[pindex
] = values
[reg
];
2863 if (ainfo
->storage
== LLVMArgVtypeInReg
) {
2865 LLVMValueRef regs
[2];
2870 g_assert (addresses
[reg
]);
2872 emit_vtype_to_reg (ctx
, builder
, sig
->params
[i
- sig
->hasthis
], addresses
[reg
], ainfo
, regs
, &nregs
);
2873 for (j
= 0; j
< nregs
; ++j
)
2874 args
[pindex
++] = regs
[j
];
2877 // FIXME: Get rid of the VMOVE
2878 } else if (ainfo
->storage
== LLVMArgVtypeByVal
) {
2879 g_assert (addresses
[reg
]);
2880 args
[pindex
] = addresses
[reg
];
2881 pindexes
[i
] = pindex
;
2884 g_assert (args
[pindex
]);
2885 if (i
== 0 && sig
->hasthis
)
2886 args
[pindex
] = convert (ctx
, args
[pindex
], IntPtrType ());
2888 args
[pindex
] = convert (ctx
, args
[pindex
], type_to_llvm_arg_type (ctx
, sig
->params
[i
- sig
->hasthis
]));
2895 // FIXME: Align call sites
2901 lcall
= emit_call (ctx
, bb
, &builder
, callee
, args
, pindex
);
2903 #ifdef LLVM_MONO_BRANCH
2905 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2907 if (call
->rgctx_arg_reg
)
2908 LLVMSetInstructionCallConv (lcall
, LLVMMono1CallConv
);
2909 else if (call
->imt_arg_reg
)
2910 LLVMSetInstructionCallConv (lcall
, LLVMMono2CallConv
);
2912 if (call
->rgctx_arg_reg
)
2913 LLVMAddInstrAttribute (lcall
, 1, LLVMInRegAttribute
);
2914 if (call
->imt_arg_reg
)
2915 LLVMAddInstrAttribute (lcall
, 1 + (call
->rgctx_arg_reg
? 1 : 0), LLVMInRegAttribute
);
2918 /* Add byval attributes if needed */
2919 for (i
= 0; i
< sig
->param_count
+ sig
->hasthis
; ++i
) {
2920 LLVMArgInfo
*ainfo
= call
->cinfo
? &call
->cinfo
->args
[i
] : NULL
;
2922 if (ainfo
&& ainfo
->storage
== LLVMArgVtypeByVal
) {
2923 LLVMAddInstrAttribute (lcall
, pindexes
[i
] + 1, LLVMByValAttribute
);
2928 * Convert the result
2930 if (cinfo
&& cinfo
->ret
.storage
== LLVMArgVtypeInReg
) {
2931 LLVMValueRef regs
[2];
2933 if (!addresses
[ins
->dreg
])
2934 addresses
[ins
->dreg
] = build_alloca (ctx
, sig
->ret
);
2936 regs
[0] = LLVMBuildExtractValue (builder
, lcall
, 0, "");
2937 if (cinfo
->ret
.pair_storage
[1] != LLVMArgNone
)
2938 regs
[1] = LLVMBuildExtractValue (builder
, lcall
, 1, "");
2940 emit_reg_to_vtype (ctx
, builder
, sig
->ret
, addresses
[ins
->dreg
], &cinfo
->ret
, regs
);
2941 } else if (sig
->ret
->type
!= MONO_TYPE_VOID
&& !vretaddr
) {
2942 /* If the method returns an unsigned value, need to zext it */
2944 values
[ins
->dreg
] = convert_full (ctx
, lcall
, llvm_type_to_stack_type (type_to_llvm_type (ctx
, sig
->ret
)), type_is_unsigned (ctx
, sig
->ret
));
2950 LLVMValueRef indexes
[2];
2952 LLVMValueRef got_entry_addr
;
2955 * FIXME: Can't allocate from the cfg mempool since that is freed if
2956 * the LLVM compile fails.
2958 ji
= g_new0 (MonoJumpInfo
, 1);
2959 ji
->type
= (MonoJumpInfoType
)ins
->inst_i1
;
2960 ji
->data
.target
= ins
->inst_p0
;
2962 ji
= mono_aot_patch_info_dup (ji
);
2964 ji
->next
= cfg
->patch_info
;
2965 cfg
->patch_info
= ji
;
2967 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
2968 got_offset
= mono_aot_get_got_offset (cfg
->patch_info
);
2970 indexes
[0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
2971 indexes
[1] = LLVMConstInt (LLVMInt32Type (), (gssize
)got_offset
, FALSE
);
2972 got_entry_addr
= LLVMBuildGEP (builder
, ctx
->lmodule
->got_var
, indexes
, 2, "");
2974 // FIXME: This doesn't work right now, because it must be
2975 // paired with an invariant.end, and even then, its only in effect
2976 // inside its basic block
2979 LLVMValueRef args
[3];
2980 LLVMValueRef ptr
, val
;
2982 ptr
= LLVMBuildBitCast (builder
, got_entry_addr
, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
2984 args
[0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer
), FALSE
);
2986 val
= LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.invariant.start"), args
, 2, "");
2990 values
[ins
->dreg
] = LLVMBuildLoad (builder
, got_entry_addr
, dname
);
2993 case OP_NOT_REACHED
:
2994 LLVMBuildUnreachable (builder
);
2995 has_terminator
= TRUE
;
2996 g_assert (bb
->block_num
< cfg
->max_block_num
);
2997 unreachable
[bb
->block_num
] = TRUE
;
2998 /* Might have instructions after this */
3000 MonoInst
*next
= ins
->next
;
3001 MONO_DELETE_INS (bb
, next
);
3005 MonoInst
*var
= ins
->inst_p0
;
3007 values
[ins
->dreg
] = addresses
[var
->dreg
];
3011 LLVMValueRef args
[1];
3013 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3014 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.sin.f64"), args
, 1, dname
);
3018 LLVMValueRef args
[1];
3020 args
[0] = convert (ctx
, lhs
, LLVMDoubleType ());
3021 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.cos.f64"), args
, 1, dname
);
3024 /* test_0_sqrt_nan fails with LLVM */
3027 LLVMValueRef args [1];
3030 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3036 LLVMValueRef args
[1];
3039 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "fabs"), args
, 1, dname
);
3045 LLVMValueRef v
= LLVMBuildICmp (builder
, LLVMIntSLE
, lhs
, rhs
, "");
3046 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3051 LLVMValueRef v
= LLVMBuildICmp (builder
, LLVMIntSGE
, lhs
, rhs
, "");
3052 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3057 LLVMValueRef v
= LLVMBuildICmp (builder
, LLVMIntULE
, lhs
, rhs
, "");
3058 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3063 LLVMValueRef v
= LLVMBuildICmp (builder
, LLVMIntUGE
, lhs
, rhs
, "");
3064 values
[ins
->dreg
] = LLVMBuildSelect (builder
, v
, lhs
, rhs
, dname
);
3067 case OP_ATOMIC_EXCHANGE_I4
: {
3068 LLVMValueRef args
[2];
3070 g_assert (ins
->inst_offset
== 0);
3072 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3074 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i32.p0i32"), args
, 2, dname
);
3077 case OP_ATOMIC_EXCHANGE_I8
: {
3078 LLVMValueRef args
[2];
3080 g_assert (ins
->inst_offset
== 0);
3082 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3083 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3084 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.swap.i64.p0i64"), args
, 2, dname
);
3087 case OP_ATOMIC_ADD_NEW_I4
: {
3088 LLVMValueRef args
[2];
3090 g_assert (ins
->inst_offset
== 0);
3092 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt32Type (), 0));
3094 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i32.p0i32"), args
, 2, ""), args
[1], dname
);
3097 case OP_ATOMIC_ADD_NEW_I8
: {
3098 LLVMValueRef args
[2];
3100 g_assert (ins
->inst_offset
== 0);
3102 args
[0] = convert (ctx
, lhs
, LLVMPointerType (LLVMInt64Type (), 0));
3103 args
[1] = convert (ctx
, rhs
, LLVMInt64Type ());
3104 values
[ins
->dreg
] = LLVMBuildAdd (builder
, LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.atomic.load.add.i64.p0i64"), args
, 2, ""), args
[1], dname
);
3107 case OP_ATOMIC_CAS_I4
:
3108 case OP_ATOMIC_CAS_I8
: {
3109 LLVMValueRef args
[3];
3111 const char *intrins
;
3113 if (ins
->opcode
== OP_ATOMIC_CAS_I4
) {
3114 t
= LLVMInt32Type ();
3115 intrins
= "llvm.atomic.cmp.swap.i32.p0i32";
3117 t
= LLVMInt64Type ();
3118 intrins
= "llvm.atomic.cmp.swap.i64.p0i64";
3121 args
[0] = convert (ctx
, lhs
, LLVMPointerType (t
, 0));
3123 args
[1] = convert (ctx
, values
[ins
->sreg3
], t
);
3125 args
[2] = convert (ctx
, values
[ins
->sreg2
], t
);
3126 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, intrins
), args
, 3, dname
);
3129 case OP_MEMORY_BARRIER
: {
3130 LLVMValueRef args
[5];
3132 for (i
= 0; i
< 5; ++i
)
3133 args
[i
] = LLVMConstInt (LLVMInt1Type (), TRUE
, TRUE
);
3135 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "llvm.memory.barrier"), args
, 5, "");
3138 case OP_RELAXED_NOP
: {
3139 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3140 /* No way to get LLVM to emit this */
3141 LLVM_FAILURE (ctx
, "relaxed_nop");
3147 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3149 // 257 == FS segment register
3150 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 257);
3152 // 256 == GS segment register
3153 LLVMTypeRef ptrtype
= LLVMPointerType (IntPtrType (), 256);
3157 values
[ins
->dreg
] = LLVMBuildLoad (builder
, LLVMBuildIntToPtr (builder
, LLVMConstInt (IntPtrType (), ins
->inst_offset
, TRUE
), ptrtype
, ""), "");
3159 LLVM_FAILURE (ctx
, "opcode tls-get");
3169 case OP_IADD_OVF_UN
:
3171 case OP_ISUB_OVF_UN
:
3173 case OP_IMUL_OVF_UN
:
3174 #if SIZEOF_VOID_P == 8
3176 case OP_LADD_OVF_UN
:
3178 case OP_LSUB_OVF_UN
:
3180 case OP_LMUL_OVF_UN
:
3183 LLVMValueRef args
[2], val
, ovf
, func
;
3185 emit_cond_throw_pos (ctx
);
3187 args
[0] = convert (ctx
, lhs
, op_to_llvm_type (ins
->opcode
));
3188 args
[1] = convert (ctx
, rhs
, op_to_llvm_type (ins
->opcode
));
3189 func
= LLVMGetNamedFunction (module
, ovf_op_to_intrins (ins
->opcode
));
3191 val
= LLVMBuildCall (builder
, func
, args
, 2, "");
3192 values
[ins
->dreg
] = LLVMBuildExtractValue (builder
, val
, 0, dname
);
3193 ovf
= LLVMBuildExtractValue (builder
, val
, 1, "");
3194 emit_cond_system_exception (ctx
, bb
, "OverflowException", ovf
);
3195 CHECK_FAILURE (ctx
);
3196 builder
= ctx
->builder
;
3202 * We currently model them using arrays. Promotion to local vregs is
3203 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3204 * so we always have an entry in cfg->varinfo for them.
3205 * FIXME: Is this needed ?
3208 MonoClass
*klass
= ins
->klass
;
3209 LLVMValueRef args
[5];
3213 LLVM_FAILURE (ctx
, "!klass");
3217 if (!addresses
[ins
->dreg
])
3218 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3219 args
[0] = LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3220 args
[1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE
);
3221 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3223 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3224 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3225 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memset_func_name
), args
, memset_param_count
, "");
3229 case OP_STOREV_MEMBASE
:
3230 case OP_LOADV_MEMBASE
:
3232 MonoClass
*klass
= ins
->klass
;
3233 LLVMValueRef src
, dst
, args
[5];
3234 gboolean done
= FALSE
;
3238 LLVM_FAILURE (ctx
, "!klass");
3242 switch (ins
->opcode
) {
3243 case OP_STOREV_MEMBASE
:
3244 if (!addresses
[ins
->sreg1
]) {
3246 g_assert (values
[ins
->sreg1
]);
3247 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));
3248 LLVMBuildStore (builder
, values
[ins
->sreg1
], dst
);
3251 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3252 dst
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_destbasereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3255 case OP_LOADV_MEMBASE
:
3256 if (!addresses
[ins
->dreg
])
3257 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3258 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (LLVMInt8Type (), 0));
3259 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3262 if (!addresses
[ins
->sreg1
])
3263 addresses
[ins
->sreg1
] = build_alloca (ctx
, &klass
->byval_arg
);
3264 if (!addresses
[ins
->dreg
])
3265 addresses
[ins
->dreg
] = build_alloca (ctx
, &klass
->byval_arg
);
3266 src
= LLVMBuildBitCast (builder
, addresses
[ins
->sreg1
], LLVMPointerType (LLVMInt8Type (), 0), "");
3267 dst
= LLVMBuildBitCast (builder
, addresses
[ins
->dreg
], LLVMPointerType (LLVMInt8Type (), 0), "");
3270 g_assert_not_reached ();
3278 args
[2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass
, NULL
), FALSE
);
3279 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3281 args
[3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE
);
3282 args
[4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE
);
3283 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, memcpy_func_name
), args
, memcpy_param_count
, "");
3286 case OP_LLVM_OUTARG_VT
:
3287 if (!addresses
[ins
->sreg1
]) {
3288 addresses
[ins
->sreg1
] = build_alloca (ctx
, &ins
->klass
->byval_arg
);
3289 g_assert (values
[ins
->sreg1
]);
3290 LLVMBuildStore (builder
, values
[ins
->sreg1
], addresses
[ins
->sreg1
]);
3292 addresses
[ins
->dreg
] = addresses
[ins
->sreg1
];
3298 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3300 values
[ins
->dreg
] = LLVMConstNull (type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
));
3303 case OP_LOADX_MEMBASE
: {
3304 LLVMTypeRef t
= type_to_llvm_type (ctx
, &ins
->klass
->byval_arg
);
3307 src
= convert (ctx
, LLVMBuildAdd (builder
, convert (ctx
, values
[ins
->inst_basereg
], IntPtrType ()), LLVMConstInt (IntPtrType (), ins
->inst_offset
, FALSE
), ""), LLVMPointerType (t
, 0));
3308 values
[ins
->dreg
] = mono_llvm_build_aligned_load (builder
, src
, "", FALSE
, 1);
3315 values
[ins
->dreg
] = LLVMBuildAdd (builder
, lhs
, rhs
, "");
3319 values
[ins
->dreg
] = LLVMBuildFAdd (builder
, lhs
, rhs
, "");
3325 values
[ins
->dreg
] = LLVMBuildSub (builder
, lhs
, rhs
, "");
3329 values
[ins
->dreg
] = LLVMBuildFSub (builder
, lhs
, rhs
, "");
3333 values
[ins
->dreg
] = LLVMBuildFMul (builder
, lhs
, rhs
, "");
3337 values
[ins
->dreg
] = LLVMBuildFDiv (builder
, lhs
, rhs
, "");
3340 values
[ins
->dreg
] = LLVMBuildAnd (builder
, lhs
, rhs
, "");
3343 values
[ins
->dreg
] = LLVMBuildOr (builder
, lhs
, rhs
, "");
3346 values
[ins
->dreg
] = LLVMBuildXor (builder
, lhs
, rhs
, "");
3359 switch (ins
->opcode
) {
3364 t
= LLVMVectorType (LLVMInt32Type (), 4);
3365 rt
= LLVMVectorType (LLVMFloatType (), 4);
3371 t
= LLVMVectorType (LLVMInt64Type (), 2);
3372 rt
= LLVMVectorType (LLVMDoubleType (), 2);
3375 t
= LLVMInt32Type ();
3376 rt
= LLVMInt32Type ();
3377 g_assert_not_reached ();
3380 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3381 rhs
= LLVMBuildBitCast (builder
, rhs
, t
, "");
3382 switch (ins
->opcode
) {
3385 v
= LLVMBuildAnd (builder
, lhs
, rhs
, "");
3389 v
= LLVMBuildOr (builder
, lhs
, rhs
, "");
3393 v
= LLVMBuildXor (builder
, lhs
, rhs
, "");
3397 v
= LLVMBuildAnd (builder
, rhs
, LLVMBuildNot (builder
, lhs
, ""), "");
3400 values
[ins
->dreg
] = LLVMBuildBitCast (builder
, v
, rt
, "");
3413 LLVMValueRef args
[2];
3418 values
[ins
->dreg
] = LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, simd_op_to_intrins (ins
->opcode
)), args
, 2, dname
);
3427 case OP_EXTRACT_U1
: {
3429 gboolean zext
= FALSE
;
3431 switch (ins
->opcode
) {
3433 t
= LLVMVectorType (LLVMDoubleType (), 2);
3436 t
= LLVMVectorType (LLVMInt64Type (), 2);
3439 t
= LLVMVectorType (LLVMInt32Type (), 4);
3442 t
= LLVMVectorType (LLVMInt16Type (), 8);
3445 t
= LLVMVectorType (LLVMInt16Type (), 8);
3449 t
= LLVMVectorType (LLVMInt8Type (), 16);
3452 t
= LLVMVectorType (LLVMInt8Type (), 16);
3456 t
= LLVMInt32Type ();
3457 g_assert_not_reached ();
3460 lhs
= LLVMBuildBitCast (builder
, lhs
, t
, "");
3461 values
[ins
->dreg
] = LLVMBuildExtractElement (builder
, lhs
, LLVMConstInt (LLVMInt32Type (), ins
->inst_c0
, FALSE
), "");
3463 values
[ins
->dreg
] = LLVMBuildZExt (builder
, values
[ins
->dreg
], LLVMInt32Type (), "");
3472 * EXCEPTION HANDLING
3474 case OP_IMPLICIT_EXCEPTION
:
3475 /* This marks a place where an implicit exception can happen */
3476 if (bb
->region
!= -1)
3477 LLVM_FAILURE (ctx
, "implicit-exception");
3481 MonoMethodSignature
*throw_sig
;
3482 LLVMValueRef callee
, arg
;
3483 gboolean rethrow
= (ins
->opcode
== OP_RETHROW
);
3484 const char *icall_name
;
3486 callee
= rethrow
? ctx
->lmodule
->rethrow
: ctx
->lmodule
->throw;
3487 icall_name
= rethrow
? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3490 throw_sig
= mono_metadata_signature_alloc (mono_defaults
.corlib
, 1);
3491 throw_sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
3492 throw_sig
->params
[0] = &mono_defaults
.object_class
->byval_arg
;
3493 if (cfg
->compile_aot
) {
3494 callee
= get_plt_entry (ctx
, sig_to_llvm_sig (ctx
, throw_sig
, NULL
), MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
);
3496 callee
= LLVMAddFunction (module
, icall_name
, sig_to_llvm_sig (ctx
, throw_sig
, NULL
));
3500 * LLVM doesn't push the exception argument, so we need a different
3503 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, rethrow
? "mono_arch_llvm_rethrow_exception" : "mono_arch_llvm_throw_exception"));
3505 LLVMAddGlobalMapping (ee
, callee
, resolve_patch (cfg
, MONO_PATCH_INFO_INTERNAL_METHOD
, icall_name
));
3509 mono_memory_barrier ();
3511 ctx
->lmodule
->rethrow
= callee
;
3513 ctx
->lmodule
->throw = callee
;
3515 arg
= convert (ctx
, values
[ins
->sreg1
], type_to_llvm_type (ctx
, &mono_defaults
.object_class
->byval_arg
));
3516 emit_call (ctx
, bb
, &builder
, callee
, &arg
, 1);
3519 case OP_CALL_HANDLER
: {
3521 * We don't 'call' handlers, but instead simply branch to them.
3522 * The code generated by ENDFINALLY will branch back to us.
3524 LLVMBasicBlockRef finally_bb
, noex_bb
;
3527 finally_bb
= get_bb (ctx
, ins
->inst_target_bb
);
3529 bb_list
= bblocks
[ins
->inst_target_bb
->block_num
].call_handler_return_bbs
;
3532 * Set the indicator variable for the finally clause.
3534 lhs
= bblocks
[ins
->inst_target_bb
->block_num
].finally_ind
;
3536 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list
) + 1, FALSE
), lhs
);
3538 /* Branch to the finally clause */
3539 LLVMBuildBr (builder
, finally_bb
);
3541 noex_bb
= gen_bb (ctx
, "CALL_HANDLER_CONT_BB");
3542 // FIXME: Use a mempool
3543 bblocks
[ins
->inst_target_bb
->block_num
].call_handler_return_bbs
= g_slist_append (bblocks
[ins
->inst_target_bb
->block_num
].call_handler_return_bbs
, noex_bb
);
3545 builder
= ctx
->builder
= create_builder (ctx
);
3546 LLVMPositionBuilderAtEnd (ctx
->builder
, noex_bb
);
3548 bblocks
[bb
->block_num
].end_bblock
= noex_bb
;
3551 case OP_START_HANDLER
: {
3554 case OP_ENDFINALLY
: {
3555 LLVMBasicBlockRef resume_bb
;
3556 MonoBasicBlock
*handler_bb
;
3557 LLVMValueRef val
, switch_ins
;
3560 handler_bb
= g_hash_table_lookup (ctx
->region_to_handler
, GUINT_TO_POINTER (mono_get_block_region_notry (cfg
, bb
->region
)));
3561 g_assert (handler_bb
);
3562 lhs
= bblocks
[handler_bb
->block_num
].finally_ind
;
3565 bb_list
= bblocks
[handler_bb
->block_num
].call_handler_return_bbs
;
3567 resume_bb
= gen_bb (ctx
, "ENDFINALLY_RESUME_BB");
3569 /* Load the finally variable */
3570 val
= LLVMBuildLoad (builder
, lhs
, "");
3572 /* Reset the variable */
3573 LLVMBuildStore (builder
, LLVMConstInt (LLVMInt32Type (), 0, FALSE
), lhs
);
3575 /* Branch to either resume_bb, or to the bblocks in bb_list */
3576 switch_ins
= LLVMBuildSwitch (builder
, val
, resume_bb
, g_slist_length (bb_list
));
3578 * The other targets are added at the end to handle OP_CALL_HANDLER
3579 * opcodes processed later.
3581 bblocks
[handler_bb
->block_num
].endfinally_switch
= switch_ins
;
3583 for (i = 0; i < g_slist_length (bb_list); ++i)
3584 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
3587 builder
= ctx
->builder
= create_builder (ctx
);
3588 LLVMPositionBuilderAtEnd (ctx
->builder
, resume_bb
);
3590 LLVMBuildCall (builder
, LLVMGetNamedFunction (module
, "mono_resume_unwind"), NULL
, 0, "");
3591 LLVMBuildUnreachable (builder
);
3592 has_terminator
= TRUE
;
3598 sprintf (reason
, "opcode %s", mono_inst_name (ins
->opcode
));
3599 LLVM_FAILURE (ctx
, reason
);
3604 /* Convert the value to the type required by phi nodes */
3605 if (spec
[MONO_INST_DEST
] != ' ' && !MONO_IS_STORE_MEMBASE (ins
) && vreg_types
[ins
->dreg
]) {
3606 if (!values
[ins
->dreg
])
3608 values
[ins
->dreg
] = addresses
[ins
->dreg
];
3610 values
[ins
->dreg
] = convert (ctx
, values
[ins
->dreg
], vreg_types
[ins
->dreg
]);
3613 /* Add stores for volatile variables */
3614 if (spec
[MONO_INST_DEST
] != ' ' && spec
[MONO_INST_DEST
] != 'v' && !MONO_IS_STORE_MEMBASE (ins
))
3615 emit_volatile_store (ctx
, ins
->dreg
);
3618 if (!has_terminator
&& bb
->next_bb
&& (bb
== cfg
->bb_entry
|| bb
->in_count
> 0))
3619 LLVMBuildBr (builder
, get_bb (ctx
, bb
->next_bb
));
3621 if (bb
== cfg
->bb_exit
&& sig
->ret
->type
== MONO_TYPE_VOID
)
3622 LLVMBuildRetVoid (builder
);
3624 if (bb
== cfg
->bb_entry
)
3625 ctx
->last_alloca
= LLVMGetLastInstruction (get_bb (ctx
, cfg
->bb_entry
));
3628 /* Add incoming phi values */
3629 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3630 GSList
*l
, *ins_list
;
3632 ins_list
= bblocks
[bb
->block_num
].phi_nodes
;
3634 for (l
= ins_list
; l
; l
= l
->next
) {
3635 PhiNode
*node
= l
->data
;
3636 MonoInst
*phi
= node
->phi
;
3637 int sreg1
= node
->sreg
;
3638 LLVMBasicBlockRef in_bb
;
3643 in_bb
= get_end_bb (ctx
, node
->in_bb
);
3645 if (unreachable
[node
->in_bb
->block_num
])
3648 g_assert (values
[sreg1
]);
3650 g_assert (LLVMTypeOf (values
[sreg1
]) == LLVMTypeOf (values
[phi
->dreg
]));
3651 LLVMAddIncoming (values
[phi
->dreg
], &values
[sreg1
], &in_bb
, 1);
3655 /* Create the SWITCH statements for ENDFINALLY instructions */
3656 for (bb
= cfg
->bb_entry
; bb
; bb
= bb
->next_bb
) {
3657 if (bblocks
[bb
->block_num
].endfinally_switch
) {
3658 LLVMValueRef switch_ins
= bblocks
[bb
->block_num
].endfinally_switch
;
3659 GSList
*bb_list
= bblocks
[bb
->block_num
].call_handler_return_bbs
;
3661 for (i
= 0; i
< g_slist_length (bb_list
); ++i
)
3662 LLVMAddCase (switch_ins
, LLVMConstInt (LLVMInt32Type (), i
+ 1, FALSE
), g_slist_nth (bb_list
, i
)->data
);
3666 if (cfg
->verbose_level
> 1)
3667 mono_llvm_dump_value (method
);
3669 mark_as_used (module
, method
);
3671 if (cfg
->compile_aot
) {
3672 /* Don't generate native code, keep the LLVM IR */
3674 /* Can't delete the method if it has an alias, so only add it if successful */
3676 debug_alias
= LLVMAddAlias (module
, LLVMTypeOf (method
), method
, debug_name
);
3677 LLVMSetLinkage (debug_alias
, LLVMInternalLinkage
);
3678 LLVMSetVisibility (debug_alias
, LLVMHiddenVisibility
);
3681 if (cfg
->compile_aot
&& cfg
->verbose_level
)
3682 printf ("%s emitted as %s\n", mono_method_full_name (cfg
->method
, TRUE
), method_name
);
3684 //LLVMVerifyFunction(method, 0);
3686 mono_llvm_optimize_method (method
);
3688 if (cfg
->verbose_level
> 1)
3689 mono_llvm_dump_value (method
);
3691 cfg
->native_code
= LLVMGetPointerToGlobal (ee
, method
);
3693 /* Set by emit_cb */
3694 g_assert (cfg
->code_len
);
3696 /* FIXME: Free the LLVM IL for the function */
3704 /* Need to add unused phi nodes as they can be referenced by other values */
3705 LLVMBasicBlockRef phi_bb
= LLVMAppendBasicBlock (method
, "PHI_BB");
3706 LLVMBuilderRef builder
;
3708 builder
= create_builder (ctx
);
3709 LLVMPositionBuilderAtEnd (builder
, phi_bb
);
3711 for (i
= 0; i
< phi_values
->len
; ++i
) {
3712 LLVMValueRef v
= g_ptr_array_index (phi_values
, i
);
3713 if (LLVMGetInstructionParent (v
) == NULL
)
3714 LLVMInsertIntoBuilder (builder
, v
);
3717 LLVMDeleteFunction (method
);
3723 g_free (vreg_types
);
3724 g_free (vreg_cli_types
);
3726 g_free (debug_name
);
3727 g_ptr_array_free (phi_values
, TRUE
);
3728 g_free (ctx
->bblocks
);
3729 g_hash_table_destroy (ctx
->region_to_handler
);
3730 g_free (method_name
);
3731 g_ptr_array_free (bblock_list
, TRUE
);
3733 for (l
= ctx
->builders
; l
; l
= l
->next
) {
3734 LLVMBuilderRef builder
= l
->data
;
3735 LLVMDisposeBuilder (builder
);
3740 TlsSetValue (current_cfg_tls_id
, NULL
);
3742 mono_loader_unlock ();
3746 * mono_llvm_emit_call:
3748 * Same as mono_arch_emit_call () for LLVM.
3751 mono_llvm_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
3754 MonoMethodSignature
*sig
;
3755 int i
, n
, stack_size
;
3760 sig
= call
->signature
;
3761 n
= sig
->param_count
+ sig
->hasthis
;
3763 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
3765 if (cfg
->disable_llvm
)
3768 if (sig
->call_convention
== MONO_CALL_VARARG
) {
3769 cfg
->exception_message
= g_strdup ("varargs");
3770 cfg
->disable_llvm
= TRUE
;
3773 for (i
= 0; i
< n
; ++i
) {
3776 ainfo
= call
->cinfo
->args
+ i
;
3778 in
= call
->args
[i
];
3780 /* Simply remember the arguments */
3781 switch (ainfo
->storage
) {
3783 MONO_INST_NEW (cfg
, ins
, OP_MOVE
);
3784 ins
->dreg
= mono_alloc_ireg (cfg
);
3785 ins
->sreg1
= in
->dreg
;
3787 case LLVMArgInFPReg
:
3788 MONO_INST_NEW (cfg
, ins
, OP_FMOVE
);
3789 ins
->dreg
= mono_alloc_freg (cfg
);
3790 ins
->sreg1
= in
->dreg
;
3792 case LLVMArgVtypeByVal
:
3793 case LLVMArgVtypeInReg
:
3794 MONO_INST_NEW (cfg
, ins
, OP_LLVM_OUTARG_VT
);
3795 ins
->dreg
= mono_alloc_ireg (cfg
);
3796 ins
->sreg1
= in
->dreg
;
3797 ins
->klass
= mono_class_from_mono_type (sig
->params
[i
- sig
->hasthis
]);
3800 call
->cinfo
= mono_arch_get_llvm_call_info (cfg
, sig
);
3801 cfg
->exception_message
= g_strdup ("ainfo->storage");
3802 cfg
->disable_llvm
= TRUE
;
3806 if (!cfg
->disable_llvm
) {
3807 MONO_ADD_INS (cfg
->cbb
, ins
);
3808 mono_call_inst_add_outarg_reg (cfg
, call
, ins
->dreg
, 0, FALSE
);
3813 static unsigned char*
3814 alloc_cb (LLVMValueRef function
, int size
)
3818 cfg
= TlsGetValue (current_cfg_tls_id
);
3822 return mono_domain_code_reserve (cfg
->domain
, size
);
3824 return mono_domain_code_reserve (mono_domain_get (), size
);
3829 emitted_cb (LLVMValueRef function
, void *start
, void *end
)
3833 cfg
= TlsGetValue (current_cfg_tls_id
);
3835 cfg
->code_len
= (guint8
*)end
- (guint8
*)start
;
3839 exception_cb (void *data
)
3842 MonoJitExceptionInfo
*ei
;
3844 gpointer
*type_info
;
3845 int this_reg
, this_offset
;
3847 cfg
= TlsGetValue (current_cfg_tls_id
);
3851 * data points to a DWARF FDE structure, convert it to our unwind format and
3853 * An alternative would be to save it directly, and modify our unwinder to work
3856 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
);
3858 cfg
->llvm_ex_info
= mono_mempool_alloc0 (cfg
->mempool
, ei_len
* sizeof (MonoJitExceptionInfo
));
3859 cfg
->llvm_ex_info_len
= ei_len
;
3860 memcpy (cfg
->llvm_ex_info
, ei
, ei_len
* sizeof (MonoJitExceptionInfo
));
3861 /* Fill the rest of the information from the type info */
3862 for (i
= 0; i
< ei_len
; ++i
) {
3863 gint32 clause_index
= *(gint32
*)type_info
[i
];
3864 MonoExceptionClause
*clause
= &cfg
->header
->clauses
[clause_index
];
3866 cfg
->llvm_ex_info
[i
].flags
= clause
->flags
;
3867 cfg
->llvm_ex_info
[i
].data
.catch_class
= clause
->data
.catch_class
;
3869 cfg
->llvm_this_reg
= this_reg
;
3870 cfg
->llvm_this_offset
= this_offset
;
3876 add_intrinsics (LLVMModuleRef module
)
3878 /* Emit declarations of instrinsics */
3880 LLVMTypeRef memset_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
3882 #if LLVM_CHECK_VERSION(2, 8)
3883 memset_param_count
= 5;
3884 memset_func_name
= "llvm.memset.p0i8.i32";
3886 memset_param_count
= 4;
3887 memset_func_name
= "llvm.memset.i32";
3889 LLVMAddFunction (module
, memset_func_name
, LLVMFunctionType (LLVMVoidType (), memset_params
, memset_param_count
, FALSE
));
3893 LLVMTypeRef memcpy_params
[] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
3895 #if LLVM_CHECK_VERSION(2, 8)
3896 memcpy_param_count
= 5;
3897 memcpy_func_name
= "llvm.memcpy.p0i8.p0i8.i32";
3899 memcpy_param_count
= 4;
3900 memcpy_func_name
= "llvm.memcpy.i32";
3903 LLVMAddFunction (module
, memcpy_func_name
, LLVMFunctionType (LLVMVoidType (), memcpy_params
, memcpy_param_count
, FALSE
));
3907 LLVMTypeRef params
[] = { LLVMDoubleType () };
3909 LLVMAddFunction (module
, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
3910 LLVMAddFunction (module
, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
3911 LLVMAddFunction (module
, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
3913 /* This isn't an intrinsic, instead llvm seems to special case it by name */
3914 LLVMAddFunction (module
, "fabs", LLVMFunctionType (LLVMDoubleType (), params
, 1, FALSE
));
3918 LLVMTypeRef membar_params
[] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
3920 LLVMAddFunction (module
, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
3921 LLVMAddFunction (module
, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
3922 LLVMAddFunction (module
, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE
));
3923 LLVMAddFunction (module
, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE
));
3924 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE
));
3925 LLVMAddFunction (module
, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE
));
3926 LLVMAddFunction (module
, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params
, 5, FALSE
));
3930 LLVMTypeRef ovf_res_i32
[] = { LLVMInt32Type (), LLVMInt1Type () };
3931 LLVMTypeRef ovf_params_i32
[] = { LLVMInt32Type (), LLVMInt32Type () };
3933 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3934 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3935 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3936 LLVMAddFunction (module
, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3937 LLVMAddFunction (module
, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3938 LLVMAddFunction (module
, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32
, 2, FALSE
), ovf_params_i32
, 2, FALSE
));
3942 LLVMTypeRef ovf_res_i64
[] = { LLVMInt64Type (), LLVMInt1Type () };
3943 LLVMTypeRef ovf_params_i64
[] = { LLVMInt64Type (), LLVMInt64Type () };
3945 LLVMAddFunction (module
, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3946 LLVMAddFunction (module
, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3947 LLVMAddFunction (module
, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3948 LLVMAddFunction (module
, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3949 LLVMAddFunction (module
, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3950 LLVMAddFunction (module
, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64
, 2, FALSE
), ovf_params_i64
, 2, FALSE
));
3954 LLVMTypeRef struct_ptr
= LLVMPointerType (LLVMStructType (NULL
, 0, FALSE
), 0);
3955 LLVMTypeRef invariant_start_params
[] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3956 LLVMTypeRef invariant_end_params
[] = { struct_ptr
, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3958 LLVMAddFunction (module
, "llvm.invariant.start", LLVMFunctionType (struct_ptr
, invariant_start_params
, 2, FALSE
));
3960 LLVMAddFunction (module
, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params
, 3, FALSE
));
3965 LLVMTypeRef arg_types
[2];
3966 LLVMTypeRef ret_type
;
3968 arg_types
[0] = LLVMPointerType (LLVMInt8Type (), 0);
3969 arg_types
[1] = LLVMPointerType (LLVMInt8Type (), 0);
3970 #if LLVM_CHECK_VERSION(2, 8)
3971 eh_selector_name
= "llvm.eh.selector";
3972 ret_type
= LLVMInt32Type ();
3974 #if SIZEOF_VOID_P == 8
3975 eh_selector_name
= "llvm.eh.selector.i64";
3976 ret_type
= LLVMInt64Type ();
3978 eh_selector_name
= "llvm.eh.selector.i32";
3979 ret_type
= LLVMInt32Type ();
3982 LLVMAddFunction (module
, eh_selector_name
, LLVMFunctionType (ret_type
, arg_types
, 2, TRUE
));
3984 LLVMAddFunction (module
, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL
, 0, FALSE
));
3986 LLVMAddFunction (module
, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
3988 LLVMAddFunction (module
, "mono_resume_unwind", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
3991 /* SSE intrinsics */
3993 LLVMTypeRef vector_type
, arg_types
[2];
3995 vector_type
= LLVMVectorType (LLVMInt32Type (), 4);
3996 arg_types
[0] = vector_type
;
3997 arg_types
[1] = vector_type
;
3998 LLVMAddFunction (module
, "llvm.x86.sse41.pminud", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
3999 LLVMAddFunction (module
, "llvm.x86.sse41.pmaxud", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4001 vector_type
= LLVMVectorType (LLVMInt16Type (), 8);
4002 arg_types
[0] = vector_type
;
4003 arg_types
[1] = vector_type
;
4004 LLVMAddFunction (module
, "llvm.x86.sse41.pminuw", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4005 LLVMAddFunction (module
, "llvm.x86.sse41.pmaxuw", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4007 vector_type
= LLVMVectorType (LLVMInt8Type (), 16);
4008 arg_types
[0] = vector_type
;
4009 arg_types
[1] = vector_type
;
4010 LLVMAddFunction (module
, "llvm.x86.sse2.pminu.b", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4011 LLVMAddFunction (module
, "llvm.x86.sse2.pmaxu.b", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4013 vector_type
= LLVMVectorType (LLVMDoubleType (), 2);
4014 arg_types
[0] = vector_type
;
4015 arg_types
[1] = vector_type
;
4016 LLVMAddFunction (module
, "llvm.x86.sse2.min.pd", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4017 LLVMAddFunction (module
, "llvm.x86.sse2.max.pd", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4019 vector_type
= LLVMVectorType (LLVMFloatType (), 4);
4020 arg_types
[0] = vector_type
;
4021 arg_types
[1] = vector_type
;
4022 LLVMAddFunction (module
, "llvm.x86.sse2.min.ps", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4023 LLVMAddFunction (module
, "llvm.x86.sse2.max.ps", LLVMFunctionType (vector_type
, arg_types
, 2, FALSE
));
4028 mono_llvm_init (void)
4030 current_cfg_tls_id
= TlsAlloc ();
4034 init_jit_module (void)
4036 if (jit_module_inited
)
4039 mono_loader_lock ();
4041 if (jit_module_inited
) {
4042 mono_loader_unlock ();
4046 jit_module
.module
= LLVMModuleCreateWithName ("mono");
4048 ee
= mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module
.module
), alloc_cb
, emitted_cb
, exception_cb
);
4050 add_intrinsics (jit_module
.module
);
4052 jit_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
4054 LLVMAddGlobalMapping (ee
, LLVMGetNamedFunction (jit_module
.module
, "mono_resume_unwind"), mono_resume_unwind
);
4056 jit_module_inited
= TRUE
;
4058 mono_loader_unlock ();
4062 mono_llvm_cleanup (void)
4065 mono_llvm_dispose_ee (ee
);
4067 if (jit_module
.llvm_types
)
4068 g_hash_table_destroy (jit_module
.llvm_types
);
4072 mono_llvm_create_aot_module (const char *got_symbol
)
4074 /* Delete previous module */
4075 if (aot_module
.plt_entries
)
4076 g_hash_table_destroy (aot_module
.plt_entries
);
4078 memset (&aot_module
, 0, sizeof (aot_module
));
4080 aot_module
.module
= LLVMModuleCreateWithName ("aot");
4081 aot_module
.got_symbol
= got_symbol
;
4083 add_intrinsics (aot_module
.module
);
4087 * We couldn't compute the type of the LLVM global representing the got because
4088 * its size is only known after all the methods have been emitted. So create
4089 * a dummy variable, and replace all uses it with the real got variable when
4090 * its size is known in mono_llvm_emit_aot_module ().
4093 LLVMTypeRef got_type
= LLVMArrayType (IntPtrType (), 0);
4095 aot_module
.got_var
= LLVMAddGlobal (aot_module
.module
, got_type
, "mono_dummy_got");
4096 LLVMSetInitializer (aot_module
.got_var
, LLVMConstNull (got_type
));
4099 /* Add a dummy personality function */
4101 LLVMBasicBlockRef lbb
;
4102 LLVMBuilderRef lbuilder
;
4103 LLVMValueRef personality
;
4105 personality
= LLVMAddFunction (aot_module
.module
, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL
, 0, FALSE
));
4106 LLVMSetLinkage (personality
, LLVMPrivateLinkage
);
4107 lbb
= LLVMAppendBasicBlock (personality
, "BB0");
4108 lbuilder
= LLVMCreateBuilder ();
4109 LLVMPositionBuilderAtEnd (lbuilder
, lbb
);
4110 LLVMBuildRetVoid (lbuilder
);
4113 aot_module
.llvm_types
= g_hash_table_new (NULL
, NULL
);
4114 aot_module
.plt_entries
= g_hash_table_new (g_str_hash
, g_str_equal
);
4118 * Emit the aot module into the LLVM bitcode file FILENAME.
4121 mono_llvm_emit_aot_module (const char *filename
, int got_size
)
4123 LLVMTypeRef got_type
;
4124 LLVMValueRef real_got
;
4127 * Create the real got variable and replace all uses of the dummy variable with
4130 got_type
= LLVMArrayType (IntPtrType (), got_size
);
4131 real_got
= LLVMAddGlobal (aot_module
.module
, got_type
, aot_module
.got_symbol
);
4132 LLVMSetInitializer (real_got
, LLVMConstNull (got_type
));
4133 LLVMSetLinkage (real_got
, LLVMInternalLinkage
);
4135 mono_llvm_replace_uses_of (aot_module
.got_var
, real_got
);
4137 mark_as_used (aot_module
.module
, real_got
);
4139 /* Delete the dummy got so it doesn't become a global */
4140 LLVMDeleteGlobal (aot_module
.got_var
);
4146 if (LLVMVerifyModule (aot_module
.module
, LLVMReturnStatusAction
, &verifier_err
)) {
4147 g_assert_not_reached ();
4152 LLVMWriteBitcodeToFile (aot_module
.module
, filename
);
4157 - Emit LLVM IR from the mono IR using the LLVM C API.
4158 - The original arch specific code remains, so we can fall back to it if we run
4159 into something we can't handle.
4161 - llvm's PrettyStackTrace class seems to register a signal handler which screws
4162 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
4166 A partial list of issues:
4167 - Handling of opcodes which can throw exceptions.
4169 In the mono JIT, these are implemented using code like this:
4176 push throw_pos - method
4177 call <exception trampoline>
4179 The problematic part is push throw_pos - method, which cannot be represented
4180 in the LLVM IR, since it does not support label values.
4181 -> this can be implemented in AOT mode using inline asm + labels, but cannot
4182 be implemented in JIT mode ?
4183 -> a possible but slower implementation would use the normal exception
4184 throwing code but it would need to control the placement of the throw code
4185 (it needs to be exactly after the compare+branch).
4186 -> perhaps add a PC offset intrinsics ?
4188 - efficient implementation of .ovf opcodes.
4190 These are currently implemented as:
4191 <ins which sets the condition codes>
4194 Some overflow opcodes are now supported by LLVM SVN.
4196 - exception handling, unwinding.
4197 - SSA is disabled for methods with exception handlers
4198 - How to obtain unwind info for LLVM compiled methods ?
4199 -> this is now solved by converting the unwind info generated by LLVM
4201 - LLVM uses the c++ exception handling framework, while we use our home grown
4202 code, and couldn't use the c++ one:
4203 - its not supported under VC++, other exotic platforms.
4204 - it might be impossible to support filter clauses with it.
4208 The trampolines need a predictable call sequence, since they need to disasm
4209 the calling code to obtain register numbers / offsets.
4211 LLVM currently generates this code in non-JIT mode:
4212 mov -0x98(%rax),%eax
4214 Here, the vtable pointer is lost.
4215 -> solution: use one vtable trampoline per class.
4217 - passing/receiving the IMT pointer/RGCTX.
4218 -> solution: pass them as normal arguments ?
4222 LLVM does not allow the specification of argument registers etc. This means
4223 that all calls are made according to the platform ABI.
4225 - passing/receiving vtypes.
4227 Vtypes passed/received in registers are handled by the front end by using
4228 a signature with scalar arguments, and loading the parts of the vtype into those
4231 Vtypes passed on the stack are handled using the 'byval' attribute.
4235 Supported though alloca, we need to emit the load/store code.
4239 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
4240 typed registers, so we have to keep track of the precise LLVM type of each vreg.
4241 This is made easier because the IR is already in SSA form.
4242 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
4243 types are frequently used incorrectly.
4248 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
4249 append the AOT data structures to that file. For methods which cannot be
4250 handled by LLVM, the normal JIT compiled versions are used.
4253 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
4254 * - each bblock should end with a branch
4255 * - setting the return value, making cfg->ret non-volatile
4256 * - merge some changes back to HEAD, to reduce the differences.
4257 * - avoid some transformations in the JIT which make it harder for us to generate
4259 * - fix memory leaks.
4260 * - use pointer types to help optimizations.