2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
34 #include "aot-compiler.h"
35 #include "mini-llvm.h"
40 extern void *memset(void *, int, size_t);
41 void bzero (void *to, size_t count) { memset (to, 0, count); }
45 #if LLVM_API_VERSION < 4
46 #error "The version of the mono llvm repository is too old."
49 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
52 * Information associated by mono with LLVM modules.
55 LLVMModuleRef lmodule;
56 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
57 GHashTable *llvm_types;
59 const char *got_symbol;
60 const char *get_method_symbol;
61 const char *get_unbox_tramp_symbol;
62 GHashTable *plt_entries;
63 GHashTable *plt_entries_ji;
64 GHashTable *method_to_lmethod;
65 GHashTable *direct_callables;
70 GPtrArray *subprogram_mds;
72 LLVMExecutionEngineRef ee;
73 gboolean external_symbols;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
101 * Information associated by the backend with mono basic blocks.
104 LLVMBasicBlockRef bblock, end_bblock;
105 LLVMValueRef finally_ind;
106 gboolean added, invoke_target;
108 * If this bblock is the start of a finally clause, this is a list of bblocks it
109 * needs to branch to in ENDFINALLY.
111 GSList *call_handler_return_bbs;
113 * If this bblock is the start of a finally clause, this is the bblock that
114 * CALL_HANDLER needs to branch to.
116 LLVMBasicBlockRef call_handler_target_bb;
117 /* The list of switch statements generated by ENDFINALLY instructions */
118 GSList *endfinally_switch_ins_list;
123 * Structure containing emit state
126 MonoMemPool *mempool;
128 /* Maps method names to the corresponding LLVMValueRef */
129 GHashTable *emitted_method_decls;
132 LLVMValueRef lmethod;
133 MonoLLVMModule *module;
134 LLVMModuleRef lmodule;
136 int sindex, default_index, ex_index;
137 LLVMBuilderRef builder;
138 LLVMValueRef *values, *addresses;
139 MonoType **vreg_cli_types;
141 MonoMethodSignature *sig;
143 GHashTable *region_to_handler;
144 GHashTable *clause_to_handler;
145 LLVMBuilderRef alloca_builder;
146 LLVMValueRef last_alloca;
147 LLVMValueRef rgctx_arg;
148 LLVMValueRef this_arg;
149 LLVMTypeRef *vreg_types;
150 LLVMTypeRef method_type;
151 LLVMBasicBlockRef init_bb, inited_bb;
153 gboolean *unreachable;
155 gboolean has_got_access;
156 gboolean is_linkonce;
157 int this_arg_pindex, rgctx_arg_pindex;
158 LLVMValueRef imt_rgctx_loc;
159 GHashTable *llvm_types;
161 MonoDebugMethodInfo *minfo;
163 /* For every clause, the clauses it is nested in */
166 GHashTable *exc_meta;
167 GHashTable *method_to_callers;
168 GPtrArray *phi_values;
169 GPtrArray *bblock_list;
171 GHashTable *jit_callees;
177 MonoBasicBlock *in_bb;
182 * Instruction metadata
183 * This is the same as ins_info, but LREG != IREG.
191 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
192 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
199 /* keep in sync with the enum in mini.h */
202 #include "mini-ops.h"
207 #if SIZEOF_VOID_P == 4
208 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
210 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
213 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
216 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
218 #define TRACE_FAILURE(msg)
222 #define IS_TARGET_X86 1
224 #define IS_TARGET_X86 0
228 #define IS_TARGET_AMD64 1
230 #define IS_TARGET_AMD64 0
233 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
265 static GHashTable *intrins_id_to_name;
266 static GHashTable *intrins_name_to_id;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
273 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
274 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
275 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
278 set_failure (EmitContext *ctx, const char *message)
280 TRACE_FAILURE (reason);
281 ctx->cfg->exception_message = g_strdup (message);
282 ctx->cfg->disable_llvm = TRUE;
288 * The LLVM type with width == sizeof (gpointer)
293 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
299 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
305 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 * Return the size of the LLVM representation of the vtype T.
314 get_vtype_size (MonoType *t)
318 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
320 /* LLVMArgAsIArgs depends on this since it stores whole words */
321 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
328 * simd_class_to_llvm_type:
330 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
333 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
335 if (!strcmp (klass->name, "Vector2d")) {
336 return LLVMVectorType (LLVMDoubleType (), 2);
337 } else if (!strcmp (klass->name, "Vector2l")) {
338 return LLVMVectorType (LLVMInt64Type (), 2);
339 } else if (!strcmp (klass->name, "Vector2ul")) {
340 return LLVMVectorType (LLVMInt64Type (), 2);
341 } else if (!strcmp (klass->name, "Vector4i")) {
342 return LLVMVectorType (LLVMInt32Type (), 4);
343 } else if (!strcmp (klass->name, "Vector4ui")) {
344 return LLVMVectorType (LLVMInt32Type (), 4);
345 } else if (!strcmp (klass->name, "Vector4f")) {
346 return LLVMVectorType (LLVMFloatType (), 4);
347 } else if (!strcmp (klass->name, "Vector8s")) {
348 return LLVMVectorType (LLVMInt16Type (), 8);
349 } else if (!strcmp (klass->name, "Vector8us")) {
350 return LLVMVectorType (LLVMInt16Type (), 8);
351 } else if (!strcmp (klass->name, "Vector16sb")) {
352 return LLVMVectorType (LLVMInt8Type (), 16);
353 } else if (!strcmp (klass->name, "Vector16b")) {
354 return LLVMVectorType (LLVMInt8Type (), 16);
356 printf ("%s\n", klass->name);
362 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
363 static inline G_GNUC_UNUSED LLVMTypeRef
364 type_to_simd_type (int type)
368 return LLVMVectorType (LLVMInt8Type (), 16);
370 return LLVMVectorType (LLVMInt16Type (), 8);
372 return LLVMVectorType (LLVMInt32Type (), 4);
374 return LLVMVectorType (LLVMInt64Type (), 2);
376 return LLVMVectorType (LLVMDoubleType (), 2);
378 return LLVMVectorType (LLVMFloatType (), 4);
380 g_assert_not_reached ();
386 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
388 int i, size, nfields, esize;
389 LLVMTypeRef *eltypes;
394 t = &klass->byval_arg;
396 if (mini_type_is_hfa (t, &nfields, &esize)) {
398 * This is needed on arm64 where HFAs are returned in
402 eltypes = g_new (LLVMTypeRef, size);
403 for (i = 0; i < size; ++i)
404 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
406 size = get_vtype_size (t);
408 eltypes = g_new (LLVMTypeRef, size);
409 for (i = 0; i < size; ++i)
410 eltypes [i] = LLVMInt8Type ();
413 name = mono_type_full_name (&klass->byval_arg);
414 ltype = LLVMStructCreateNamed (module->context, name);
415 LLVMStructSetBody (ltype, eltypes, size, FALSE);
425 * Return the LLVM type corresponding to T.
428 type_to_llvm_type (EmitContext *ctx, MonoType *t)
430 t = mini_get_underlying_type (t);
434 return LLVMVoidType ();
436 return LLVMInt8Type ();
438 return LLVMInt16Type ();
440 return LLVMInt32Type ();
442 return LLVMInt8Type ();
444 return LLVMInt16Type ();
446 return LLVMInt32Type ();
447 case MONO_TYPE_BOOLEAN:
448 return LLVMInt8Type ();
451 return LLVMInt64Type ();
453 return LLVMInt16Type ();
455 return LLVMFloatType ();
457 return LLVMDoubleType ();
460 return IntPtrType ();
461 case MONO_TYPE_OBJECT:
462 case MONO_TYPE_CLASS:
463 case MONO_TYPE_ARRAY:
464 case MONO_TYPE_SZARRAY:
465 case MONO_TYPE_STRING:
467 return ObjRefType ();
470 /* Because of generic sharing */
471 return ObjRefType ();
472 case MONO_TYPE_GENERICINST:
473 if (!mono_type_generic_inst_is_valuetype (t))
474 return ObjRefType ();
476 case MONO_TYPE_VALUETYPE:
477 case MONO_TYPE_TYPEDBYREF: {
481 klass = mono_class_from_mono_type (t);
483 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
484 return simd_class_to_llvm_type (ctx, klass);
487 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
489 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
491 ltype = create_llvm_type_for_type (ctx->module, klass);
492 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
498 printf ("X: %d\n", t->type);
499 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
500 ctx->cfg->disable_llvm = TRUE;
508 * Return whenever T is an unsigned int type.
511 type_is_unsigned (EmitContext *ctx, MonoType *t)
513 t = mini_get_underlying_type (t);
529 * type_to_llvm_arg_type:
531 * Same as type_to_llvm_type, but treat i8/i16 as i32.
534 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
536 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
538 if (ctx->cfg->llvm_only)
542 * This works on all abis except arm64/ios which passes multiple
543 * arguments in one stack slot.
546 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
548 * LLVM generates code which only sets the lower bits, while JITted
549 * code expects all the bits to be set.
551 ptype = LLVMInt32Type ();
559 * llvm_type_to_stack_type:
561 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
564 static G_GNUC_UNUSED LLVMTypeRef
565 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
569 if (type == LLVMInt8Type ())
570 return LLVMInt32Type ();
571 else if (type == LLVMInt16Type ())
572 return LLVMInt32Type ();
573 else if (!cfg->r4fp && type == LLVMFloatType ())
574 return LLVMDoubleType ();
580 * regtype_to_llvm_type:
582 * Return the LLVM type corresponding to the regtype C used in instruction
586 regtype_to_llvm_type (char c)
590 return LLVMInt32Type ();
592 return LLVMInt64Type ();
594 return LLVMDoubleType ();
603 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
606 op_to_llvm_type (int opcode)
611 return LLVMInt8Type ();
614 return LLVMInt8Type ();
617 return LLVMInt16Type ();
620 return LLVMInt16Type ();
623 return LLVMInt32Type ();
626 return LLVMInt32Type ();
628 return LLVMInt64Type ();
630 return LLVMFloatType ();
632 return LLVMDoubleType ();
634 return LLVMInt64Type ();
636 return LLVMInt32Type ();
638 return LLVMInt64Type ();
643 return LLVMInt8Type ();
648 return LLVMInt16Type ();
650 return LLVMInt32Type ();
653 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
660 return LLVMInt32Type ();
667 return LLVMInt64Type ();
669 printf ("%s\n", mono_inst_name (opcode));
670 g_assert_not_reached ();
675 #define CLAUSE_START(clause) ((clause)->try_offset)
676 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
679 * load_store_to_llvm_type:
681 * Return the size/sign/zero extension corresponding to the load/store opcode
685 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
691 case OP_LOADI1_MEMBASE:
692 case OP_STOREI1_MEMBASE_REG:
693 case OP_STOREI1_MEMBASE_IMM:
694 case OP_ATOMIC_LOAD_I1:
695 case OP_ATOMIC_STORE_I1:
698 return LLVMInt8Type ();
699 case OP_LOADU1_MEMBASE:
701 case OP_ATOMIC_LOAD_U1:
702 case OP_ATOMIC_STORE_U1:
705 return LLVMInt8Type ();
706 case OP_LOADI2_MEMBASE:
707 case OP_STOREI2_MEMBASE_REG:
708 case OP_STOREI2_MEMBASE_IMM:
709 case OP_ATOMIC_LOAD_I2:
710 case OP_ATOMIC_STORE_I2:
713 return LLVMInt16Type ();
714 case OP_LOADU2_MEMBASE:
716 case OP_ATOMIC_LOAD_U2:
717 case OP_ATOMIC_STORE_U2:
720 return LLVMInt16Type ();
721 case OP_LOADI4_MEMBASE:
722 case OP_LOADU4_MEMBASE:
725 case OP_STOREI4_MEMBASE_REG:
726 case OP_STOREI4_MEMBASE_IMM:
727 case OP_ATOMIC_LOAD_I4:
728 case OP_ATOMIC_STORE_I4:
729 case OP_ATOMIC_LOAD_U4:
730 case OP_ATOMIC_STORE_U4:
732 return LLVMInt32Type ();
733 case OP_LOADI8_MEMBASE:
735 case OP_STOREI8_MEMBASE_REG:
736 case OP_STOREI8_MEMBASE_IMM:
737 case OP_ATOMIC_LOAD_I8:
738 case OP_ATOMIC_STORE_I8:
739 case OP_ATOMIC_LOAD_U8:
740 case OP_ATOMIC_STORE_U8:
742 return LLVMInt64Type ();
743 case OP_LOADR4_MEMBASE:
744 case OP_STORER4_MEMBASE_REG:
745 case OP_ATOMIC_LOAD_R4:
746 case OP_ATOMIC_STORE_R4:
748 return LLVMFloatType ();
749 case OP_LOADR8_MEMBASE:
750 case OP_STORER8_MEMBASE_REG:
751 case OP_ATOMIC_LOAD_R8:
752 case OP_ATOMIC_STORE_R8:
754 return LLVMDoubleType ();
755 case OP_LOAD_MEMBASE:
757 case OP_STORE_MEMBASE_REG:
758 case OP_STORE_MEMBASE_IMM:
759 *size = sizeof (gpointer);
760 return IntPtrType ();
762 g_assert_not_reached ();
770 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
773 ovf_op_to_intrins (int opcode)
777 return "llvm.sadd.with.overflow.i32";
779 return "llvm.uadd.with.overflow.i32";
781 return "llvm.ssub.with.overflow.i32";
783 return "llvm.usub.with.overflow.i32";
785 return "llvm.smul.with.overflow.i32";
787 return "llvm.umul.with.overflow.i32";
789 return "llvm.sadd.with.overflow.i64";
791 return "llvm.uadd.with.overflow.i64";
793 return "llvm.ssub.with.overflow.i64";
795 return "llvm.usub.with.overflow.i64";
797 return "llvm.smul.with.overflow.i64";
799 return "llvm.umul.with.overflow.i64";
801 g_assert_not_reached ();
807 simd_op_to_intrins (int opcode)
810 #if defined(TARGET_X86) || defined(TARGET_AMD64)
812 return "llvm.x86.sse2.min.pd";
814 return "llvm.x86.sse.min.ps";
816 return "llvm.x86.sse41.pminud";
818 return "llvm.x86.sse41.pminuw";
820 return "llvm.x86.sse2.pminu.b";
822 return "llvm.x86.sse2.pmins.w";
824 return "llvm.x86.sse2.max.pd";
826 return "llvm.x86.sse.max.ps";
828 return "llvm.x86.sse3.hadd.pd";
830 return "llvm.x86.sse3.hadd.ps";
832 return "llvm.x86.sse3.hsub.pd";
834 return "llvm.x86.sse3.hsub.ps";
836 return "llvm.x86.sse41.pmaxud";
838 return "llvm.x86.sse41.pmaxuw";
840 return "llvm.x86.sse2.pmaxu.b";
842 return "llvm.x86.sse3.addsub.ps";
844 return "llvm.x86.sse3.addsub.pd";
845 case OP_EXTRACT_MASK:
846 return "llvm.x86.sse2.pmovmskb.128";
849 return "llvm.x86.sse2.psrli.w";
852 return "llvm.x86.sse2.psrli.d";
855 return "llvm.x86.sse2.psrli.q";
858 return "llvm.x86.sse2.pslli.w";
861 return "llvm.x86.sse2.pslli.d";
864 return "llvm.x86.sse2.pslli.q";
867 return "llvm.x86.sse2.psrai.w";
870 return "llvm.x86.sse2.psrai.d";
872 return "llvm.x86.sse2.padds.b";
874 return "llvm.x86.sse2.padds.w";
876 return "llvm.x86.sse2.psubs.b";
878 return "llvm.x86.sse2.psubs.w";
879 case OP_PADDB_SAT_UN:
880 return "llvm.x86.sse2.paddus.b";
881 case OP_PADDW_SAT_UN:
882 return "llvm.x86.sse2.paddus.w";
883 case OP_PSUBB_SAT_UN:
884 return "llvm.x86.sse2.psubus.b";
885 case OP_PSUBW_SAT_UN:
886 return "llvm.x86.sse2.psubus.w";
888 return "llvm.x86.sse2.pavg.b";
890 return "llvm.x86.sse2.pavg.w";
892 return "llvm.x86.sse.sqrt.ps";
894 return "llvm.x86.sse2.sqrt.pd";
896 return "llvm.x86.sse.rsqrt.ps";
898 return "llvm.x86.sse.rcp.ps";
900 return "llvm.x86.sse2.cvtdq2pd";
902 return "llvm.x86.sse2.cvtdq2ps";
904 return "llvm.x86.sse2.cvtpd2dq";
906 return "llvm.x86.sse2.cvtps2dq";
908 return "llvm.x86.sse2.cvtpd2ps";
910 return "llvm.x86.sse2.cvtps2pd";
912 return "llvm.x86.sse2.cvttpd2dq";
914 return "llvm.x86.sse2.cvttps2dq";
916 return "llvm.x86.sse.cmp.ps";
918 return "llvm.x86.sse2.cmp.pd";
920 return "llvm.x86.sse2.packsswb.128";
922 return "llvm.x86.sse2.packssdw.128";
924 return "llvm.x86.sse2.packuswb.128";
926 return "llvm.x86.sse41.packusdw";
928 return "llvm.x86.sse2.pmulh.w";
929 case OP_PMULW_HIGH_UN:
930 return "llvm.x86.sse2.pmulhu.w";
933 g_assert_not_reached ();
939 simd_op_to_llvm_type (int opcode)
941 #if defined(TARGET_X86) || defined(TARGET_AMD64)
945 return type_to_simd_type (MONO_TYPE_R8);
948 return type_to_simd_type (MONO_TYPE_I8);
951 return type_to_simd_type (MONO_TYPE_I4);
956 return type_to_simd_type (MONO_TYPE_I2);
960 return type_to_simd_type (MONO_TYPE_I1);
962 return type_to_simd_type (MONO_TYPE_R4);
965 return type_to_simd_type (MONO_TYPE_I4);
969 return type_to_simd_type (MONO_TYPE_R8);
973 return type_to_simd_type (MONO_TYPE_R4);
974 case OP_EXTRACT_MASK:
975 return type_to_simd_type (MONO_TYPE_I1);
981 return type_to_simd_type (MONO_TYPE_R4);
984 return type_to_simd_type (MONO_TYPE_R8);
986 g_assert_not_reached ();
997 * Return the LLVM basic block corresponding to BB.
999 static LLVMBasicBlockRef
1000 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1002 char bb_name_buf [128];
1005 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1006 if (bb->flags & BB_EXCEPTION_HANDLER) {
1007 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1008 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1009 bb_name = bb_name_buf;
1010 } else if (bb->block_num < 256) {
1011 if (!ctx->module->bb_names) {
1012 ctx->module->bb_names_len = 256;
1013 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1015 if (!ctx->module->bb_names [bb->block_num]) {
1018 n = g_strdup_printf ("BB%d", bb->block_num);
1019 mono_memory_barrier ();
1020 ctx->module->bb_names [bb->block_num] = n;
1022 bb_name = ctx->module->bb_names [bb->block_num];
1024 sprintf (bb_name_buf, "BB%d", bb->block_num);
1025 bb_name = bb_name_buf;
1028 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1029 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1032 return ctx->bblocks [bb->block_num].bblock;
1038 * Return the last LLVM bblock corresponding to BB.
1039 * This might not be equal to the bb returned by get_bb () since we need to generate
1040 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1042 static LLVMBasicBlockRef
1043 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1046 return ctx->bblocks [bb->block_num].end_bblock;
1049 static LLVMBasicBlockRef
1050 gen_bb (EmitContext *ctx, const char *prefix)
1054 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1055 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1061 * Return the target of the patch identified by TYPE and TARGET.
1064 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1070 memset (&ji, 0, sizeof (ji));
1072 ji.data.target = target;
1074 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1075 mono_error_assert_ok (&error);
1083 * Emit code to convert the LLVM value V to DTYPE.
1086 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1088 LLVMTypeRef stype = LLVMTypeOf (v);
1090 if (stype != dtype) {
1091 gboolean ext = FALSE;
1094 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1096 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1098 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1102 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1104 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1105 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1108 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1109 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1111 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1112 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1113 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1114 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1115 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1117 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1118 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1119 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1120 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1121 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1122 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1124 if (mono_arch_is_soft_float ()) {
1125 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1126 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1127 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1128 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1131 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1132 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1135 LLVMDumpValue (LLVMConstNull (dtype));
1136 g_assert_not_reached ();
1144 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1146 return convert_full (ctx, v, dtype, FALSE);
1150 * emit_volatile_load:
1152 * If vreg is volatile, emit a load from its address.
1155 emit_volatile_load (EmitContext *ctx, int vreg)
1159 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1160 t = ctx->vreg_cli_types [vreg];
1161 if (t && !t->byref) {
1163 * Might have to zero extend since llvm doesn't have
1166 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1167 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1168 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1169 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1170 else if (t->type == MONO_TYPE_U8)
1171 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1178 * emit_volatile_store:
1180 * If VREG is volatile, emit a store from its value to its address.
1183 emit_volatile_store (EmitContext *ctx, int vreg)
1185 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1187 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1188 g_assert (ctx->addresses [vreg]);
1189 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1194 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1196 LLVMTypeRef ret_type;
1197 LLVMTypeRef *param_types = NULL;
1202 rtype = mini_get_underlying_type (sig->ret);
1203 ret_type = type_to_llvm_type (ctx, rtype);
1207 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1211 param_types [pindex ++] = ThisType ();
1212 for (i = 0; i < sig->param_count; ++i)
1213 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1215 if (!ctx_ok (ctx)) {
1216 g_free (param_types);
1220 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1221 g_free (param_types);
1227 * sig_to_llvm_sig_full:
1229 * Return the LLVM signature corresponding to the mono signature SIG using the
1230 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1233 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1235 LLVMTypeRef ret_type;
1236 LLVMTypeRef *param_types = NULL;
1238 int i, j, pindex, vret_arg_pindex = 0;
1239 gboolean vretaddr = FALSE;
1243 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1245 rtype = mini_get_underlying_type (sig->ret);
1246 ret_type = type_to_llvm_type (ctx, rtype);
1250 switch (cinfo->ret.storage) {
1251 case LLVMArgVtypeInReg:
1252 /* LLVM models this by returning an aggregate value */
1253 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1254 LLVMTypeRef members [2];
1256 members [0] = IntPtrType ();
1257 ret_type = LLVMStructType (members, 1, FALSE);
1258 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1260 ret_type = LLVMVoidType ();
1261 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1262 LLVMTypeRef members [2];
1264 members [0] = IntPtrType ();
1265 members [1] = IntPtrType ();
1266 ret_type = LLVMStructType (members, 2, FALSE);
1268 g_assert_not_reached ();
1271 case LLVMArgVtypeByVal:
1272 /* Vtype returned normally by val */
1274 case LLVMArgVtypeAsScalar: {
1275 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1276 /* LLVM models this by returning an int */
1277 if (size < SIZEOF_VOID_P) {
1278 g_assert (cinfo->ret.nslots == 1);
1279 ret_type = LLVMIntType (size * 8);
1281 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1282 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1286 case LLVMArgFpStruct: {
1287 /* Vtype returned as a fp struct */
1288 LLVMTypeRef members [16];
1290 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1291 for (i = 0; i < cinfo->ret.nslots; ++i)
1292 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1293 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1296 case LLVMArgVtypeByRef:
1297 /* Vtype returned using a hidden argument */
1298 ret_type = LLVMVoidType ();
1300 case LLVMArgVtypeRetAddr:
1301 case LLVMArgGsharedvtFixed:
1302 case LLVMArgGsharedvtFixedVtype:
1303 case LLVMArgGsharedvtVariable:
1305 ret_type = LLVMVoidType ();
1311 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1313 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1315 * Has to be the first argument because of the sret argument attribute
1316 * FIXME: This might conflict with passing 'this' as the first argument, but
1317 * this is only used on arm64 which has a dedicated struct return register.
1319 cinfo->vret_arg_pindex = pindex;
1320 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1321 if (!ctx_ok (ctx)) {
1322 g_free (param_types);
1325 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1328 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1329 cinfo->rgctx_arg_pindex = pindex;
1330 param_types [pindex] = ctx->module->ptr_type;
1333 if (cinfo->imt_arg) {
1334 cinfo->imt_arg_pindex = pindex;
1335 param_types [pindex] = ctx->module->ptr_type;
1339 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1340 vret_arg_pindex = pindex;
1341 if (cinfo->vret_arg_index == 1) {
1342 /* Add the slots consumed by the first argument */
1343 LLVMArgInfo *ainfo = &cinfo->args [0];
1344 switch (ainfo->storage) {
1345 case LLVMArgVtypeInReg:
1346 for (j = 0; j < 2; ++j) {
1347 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1356 cinfo->vret_arg_pindex = vret_arg_pindex;
1359 if (vretaddr && vret_arg_pindex == pindex)
1360 param_types [pindex ++] = IntPtrType ();
1362 cinfo->this_arg_pindex = pindex;
1363 param_types [pindex ++] = ThisType ();
1364 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1366 if (vretaddr && vret_arg_pindex == pindex)
1367 param_types [pindex ++] = IntPtrType ();
1368 for (i = 0; i < sig->param_count; ++i) {
1369 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1371 if (vretaddr && vret_arg_pindex == pindex)
1372 param_types [pindex ++] = IntPtrType ();
1373 ainfo->pindex = pindex;
1375 switch (ainfo->storage) {
1376 case LLVMArgVtypeInReg:
1377 for (j = 0; j < 2; ++j) {
1378 switch (ainfo->pair_storage [j]) {
1380 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1385 g_assert_not_reached ();
1389 case LLVMArgVtypeByVal:
1390 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1393 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1396 case LLVMArgAsIArgs:
1397 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1400 case LLVMArgVtypeByRef:
1401 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1404 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1407 case LLVMArgAsFpArgs: {
1410 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1411 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1412 param_types [pindex ++] = LLVMDoubleType ();
1413 for (j = 0; j < ainfo->nslots; ++j)
1414 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1417 case LLVMArgVtypeAsScalar:
1418 g_assert_not_reached ();
1420 case LLVMArgGsharedvtFixed:
1421 case LLVMArgGsharedvtFixedVtype:
1422 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1424 case LLVMArgGsharedvtVariable:
1425 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1428 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1432 if (!ctx_ok (ctx)) {
1433 g_free (param_types);
1436 if (vretaddr && vret_arg_pindex == pindex)
1437 param_types [pindex ++] = IntPtrType ();
1438 if (ctx->llvm_only && cinfo->rgctx_arg) {
1439 /* Pass the rgctx as the last argument */
1440 cinfo->rgctx_arg_pindex = pindex;
1441 param_types [pindex] = ctx->module->ptr_type;
1445 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1446 g_free (param_types);
1452 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1454 return sig_to_llvm_sig_full (ctx, sig, NULL);
1458 * LLVMFunctionType1:
1460 * Create an LLVM function type from the arguments.
1462 static G_GNUC_UNUSED LLVMTypeRef
1463 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1466 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1470 * LLVMFunctionType1:
1472 * Create an LLVM function type from the arguments.
1474 static G_GNUC_UNUSED LLVMTypeRef
1475 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1476 LLVMTypeRef ParamType1,
1479 LLVMTypeRef param_types [1];
1481 param_types [0] = ParamType1;
1483 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1487 * LLVMFunctionType2:
1489 * Create an LLVM function type from the arguments.
1491 static G_GNUC_UNUSED LLVMTypeRef
1492 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1493 LLVMTypeRef ParamType1,
1494 LLVMTypeRef ParamType2,
1497 LLVMTypeRef param_types [2];
1499 param_types [0] = ParamType1;
1500 param_types [1] = ParamType2;
1502 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1506 * LLVMFunctionType3:
1508 * Create an LLVM function type from the arguments.
1510 static G_GNUC_UNUSED LLVMTypeRef
1511 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1512 LLVMTypeRef ParamType1,
1513 LLVMTypeRef ParamType2,
1514 LLVMTypeRef ParamType3,
1517 LLVMTypeRef param_types [3];
1519 param_types [0] = ParamType1;
1520 param_types [1] = ParamType2;
1521 param_types [2] = ParamType3;
1523 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1526 static G_GNUC_UNUSED LLVMTypeRef
1527 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1528 LLVMTypeRef ParamType1,
1529 LLVMTypeRef ParamType2,
1530 LLVMTypeRef ParamType3,
1531 LLVMTypeRef ParamType4,
1532 LLVMTypeRef ParamType5,
1535 LLVMTypeRef param_types [5];
1537 param_types [0] = ParamType1;
1538 param_types [1] = ParamType2;
1539 param_types [2] = ParamType3;
1540 param_types [3] = ParamType4;
1541 param_types [4] = ParamType5;
1543 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1549 * Create an LLVM builder and remember it so it can be freed later.
1551 static LLVMBuilderRef
1552 create_builder (EmitContext *ctx)
1554 LLVMBuilderRef builder = LLVMCreateBuilder ();
1556 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1562 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1567 case MONO_PATCH_INFO_INTERNAL_METHOD:
1568 name = g_strdup_printf ("jit_icall_%s", data);
1570 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1571 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1572 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1576 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1584 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1588 LLVMValueRef indexes [2];
1590 LLVMValueRef got_entry_addr, load;
1591 LLVMBuilderRef builder = ctx->builder;
1596 ji = g_new0 (MonoJumpInfo, 1);
1598 ji->data.target = data;
1600 ji = mono_aot_patch_info_dup (ji);
1602 ji->next = cfg->patch_info;
1603 cfg->patch_info = ji;
1605 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1606 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1608 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1609 * explicitly initialize it.
1611 if (!mono_aot_is_shared_got_offset (got_offset)) {
1612 //mono_print_ji (ji);
1614 ctx->has_got_access = TRUE;
1617 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1618 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1619 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1621 name = get_aotconst_name (type, data, got_offset);
1623 load = LLVMBuildLoad (builder, got_entry_addr, "");
1624 load = convert (ctx, load, llvm_type);
1625 LLVMSetValueName (load, name ? name : "");
1627 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1630 //set_invariant_load_flag (load);
1636 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1638 return get_aotconst_typed (ctx, type, data, NULL);
1642 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1644 LLVMValueRef callee;
1646 if (ctx->llvm_only) {
1647 callee_name = mono_aot_get_direct_call_symbol (type, data);
1649 /* Directly callable */
1651 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1653 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1655 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1657 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1659 /* LLVMTypeRef's are uniqued */
1660 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1661 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1663 g_free (callee_name);
1669 * Calls are made through the GOT.
1671 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1673 MonoJumpInfo *ji = NULL;
1675 callee_name = mono_aot_get_plt_symbol (type, data);
1679 if (ctx->cfg->compile_aot)
1680 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1681 mono_add_patch_info (ctx->cfg, 0, type, data);
1684 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1686 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1688 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1690 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1693 if (ctx->cfg->compile_aot) {
1694 ji = g_new0 (MonoJumpInfo, 1);
1696 ji->data.target = data;
1698 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1706 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1708 #if LLVM_API_VERSION > 100
1709 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1710 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1711 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1712 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1715 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1716 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1722 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1724 MonoMethodHeader *header = cfg->header;
1725 MonoExceptionClause *clause;
1729 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1730 return (bb->region >> 8) - 1;
1733 for (i = 0; i < header->num_clauses; ++i) {
1734 clause = &header->clauses [i];
1736 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1743 static MonoExceptionClause *
1744 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1746 // Since they're sorted by nesting we just need
1747 // the first one that the bb is a member of
1748 MonoExceptionClause *last = NULL;
1750 for (int i = 0; i < cfg->header->num_clauses; i++) {
1751 MonoExceptionClause *curr = &cfg->header->clauses [i];
1753 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1756 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1757 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1771 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1773 LLVMValueRef md_arg;
1776 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1777 md_arg = LLVMMDString ("mono", 4);
1778 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1782 set_invariant_load_flag (LLVMValueRef v)
1784 LLVMValueRef md_arg;
1786 const char *flag_name;
1788 // FIXME: Cache this
1789 flag_name = "invariant.load";
1790 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1791 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1792 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1798 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1802 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1804 MonoCompile *cfg = ctx->cfg;
1805 LLVMValueRef lcall = NULL;
1806 LLVMBuilderRef builder = *builder_ref;
1807 MonoExceptionClause *clause;
1809 if (ctx->llvm_only) {
1810 clause = get_most_deep_clause (cfg, ctx, bb);
1813 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1816 * Have to use an invoke instead of a call, branching to the
1817 * handler bblock of the clause containing this bblock.
1819 intptr_t key = CLAUSE_END(clause);
1821 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1823 // FIXME: Find the one that has the lowest end bound for the right start address
1824 // FIXME: Finally + nesting
1827 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1830 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1832 builder = ctx->builder = create_builder (ctx);
1833 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1835 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1839 int clause_index = get_handler_clause (cfg, bb);
1841 if (clause_index != -1) {
1842 MonoMethodHeader *header = cfg->header;
1843 MonoExceptionClause *ec = &header->clauses [clause_index];
1844 MonoBasicBlock *tblock;
1845 LLVMBasicBlockRef ex_bb, noex_bb;
1848 * Have to use an invoke instead of a call, branching to the
1849 * handler bblock of the clause containing this bblock.
1852 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1854 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1857 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1859 ex_bb = get_bb (ctx, tblock);
1861 noex_bb = gen_bb (ctx, "NOEX_BB");
1864 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1866 builder = ctx->builder = create_builder (ctx);
1867 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1869 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1874 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1875 ctx->builder = builder;
1879 *builder_ref = ctx->builder;
1885 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1887 const char *intrins_name;
1888 LLVMValueRef args [16], res;
1889 LLVMTypeRef addr_type;
1890 gboolean use_intrinsics = TRUE;
1892 #if LLVM_API_VERSION > 100
1893 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1894 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1895 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1896 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1897 *builder_ref = ctx->builder;
1898 use_intrinsics = FALSE;
1902 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1903 LLVMAtomicOrdering ordering;
1906 case LLVM_BARRIER_NONE:
1907 ordering = LLVMAtomicOrderingNotAtomic;
1909 case LLVM_BARRIER_ACQ:
1910 ordering = LLVMAtomicOrderingAcquire;
1912 case LLVM_BARRIER_SEQ:
1913 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1916 g_assert_not_reached ();
1921 * We handle loads which can fault by calling a mono specific intrinsic
1922 * using an invoke, so they are handled properly inside try blocks.
1923 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1924 * are marked with IntrReadArgMem.
1928 intrins_name = "llvm.mono.load.i8.p0i8";
1931 intrins_name = "llvm.mono.load.i16.p0i16";
1934 intrins_name = "llvm.mono.load.i32.p0i32";
1937 intrins_name = "llvm.mono.load.i64.p0i64";
1940 g_assert_not_reached ();
1943 addr_type = LLVMTypeOf (addr);
1944 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1945 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1948 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1949 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1950 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1951 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1953 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1954 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1955 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1956 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1963 * We emit volatile loads for loads which can fault, because otherwise
1964 * LLVM will generate invalid code when encountering a load from a
1967 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1969 /* Mark it with a custom metadata */
1972 set_metadata_flag (res, "mono.faulting.load");
1980 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1982 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1986 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1988 const char *intrins_name;
1989 LLVMValueRef args [16];
1990 gboolean use_intrinsics = TRUE;
1992 #if LLVM_API_VERSION > 100
1993 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1994 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1995 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1996 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1997 *builder_ref = ctx->builder;
1998 use_intrinsics = FALSE;
2002 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2003 LLVMAtomicOrdering ordering;
2006 case LLVM_BARRIER_NONE:
2007 ordering = LLVMAtomicOrderingNotAtomic;
2009 case LLVM_BARRIER_REL:
2010 ordering = LLVMAtomicOrderingRelease;
2012 case LLVM_BARRIER_SEQ:
2013 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2016 g_assert_not_reached ();
2022 intrins_name = "llvm.mono.store.i8.p0i8";
2025 intrins_name = "llvm.mono.store.i16.p0i16";
2028 intrins_name = "llvm.mono.store.i32.p0i32";
2031 intrins_name = "llvm.mono.store.i64.p0i64";
2034 g_assert_not_reached ();
2037 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2038 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2039 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2044 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2045 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2046 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2047 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2049 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2054 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2056 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2060 * emit_cond_system_exception:
2062 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2063 * Might set the ctx exception.
2066 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2068 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2069 LLVMBuilderRef builder;
2070 MonoClass *exc_class;
2071 LLVMValueRef args [2];
2072 LLVMValueRef callee;
2074 ex_bb = gen_bb (ctx, "EX_BB");
2076 ex2_bb = gen_bb (ctx, "EX2_BB");
2077 noex_bb = gen_bb (ctx, "NOEX_BB");
2079 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2081 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2083 /* Emit exception throwing code */
2084 ctx->builder = builder = create_builder (ctx);
2085 LLVMPositionBuilderAtEnd (builder, ex_bb);
2087 if (ctx->cfg->llvm_only) {
2088 static LLVMTypeRef sig;
2091 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2092 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2094 LLVMBuildBr (builder, ex2_bb);
2096 ctx->builder = builder = create_builder (ctx);
2097 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2099 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2100 emit_call (ctx, bb, &builder, callee, args, 1);
2101 LLVMBuildUnreachable (builder);
2103 ctx->builder = builder = create_builder (ctx);
2104 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2106 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2112 callee = ctx->module->throw_corlib_exception;
2115 const char *icall_name;
2117 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2118 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2120 if (ctx->cfg->compile_aot) {
2121 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2124 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2125 * - On x86, LLVM generated code doesn't push the arguments
2126 * - The trampoline takes the throw address as an arguments, not a pc offset.
2128 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2129 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2131 #if LLVM_API_VERSION > 100
2133 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2134 * added by emit_jit_callee ().
2136 ex2_bb = gen_bb (ctx, "EX2_BB");
2137 LLVMBuildBr (builder, ex2_bb);
2140 ctx->builder = builder = create_builder (ctx);
2141 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2143 mono_memory_barrier ();
2144 ctx->module->throw_corlib_exception = callee;
2149 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2150 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2152 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2155 * The LLVM mono branch contains changes so a block address can be passed as an
2156 * argument to a call.
2158 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2159 emit_call (ctx, bb, &builder, callee, args, 2);
2161 LLVMBuildUnreachable (builder);
2163 ctx->builder = builder = create_builder (ctx);
2164 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2166 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2173 * emit_args_to_vtype:
2175 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2178 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2180 int j, size, nslots;
2182 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2184 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2185 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2188 if (ainfo->storage == LLVMArgAsFpArgs)
2189 nslots = ainfo->nslots;
2193 for (j = 0; j < nslots; ++j) {
2194 LLVMValueRef index [2], addr, daddr;
2195 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2196 LLVMTypeRef part_type;
2198 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2201 if (ainfo->pair_storage [j] == LLVMArgNone)
2204 switch (ainfo->pair_storage [j]) {
2205 case LLVMArgInIReg: {
2206 part_type = LLVMIntType (part_size * 8);
2207 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2209 addr = LLVMBuildGEP (builder, address, index, 1, "");
2211 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2212 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2213 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2215 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2218 case LLVMArgInFPReg: {
2219 LLVMTypeRef arg_type;
2221 if (ainfo->esize == 8)
2222 arg_type = LLVMDoubleType ();
2224 arg_type = LLVMFloatType ();
2226 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2227 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2228 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2229 LLVMBuildStore (builder, args [j], addr);
2235 g_assert_not_reached ();
2238 size -= sizeof (gpointer);
2243 * emit_vtype_to_args:
2245 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2246 * into ARGS, and the number of arguments into NARGS.
2249 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2252 int j, size, nslots;
2253 LLVMTypeRef arg_type;
2255 size = get_vtype_size (t);
2257 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2258 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2260 if (ainfo->storage == LLVMArgAsFpArgs)
2261 nslots = ainfo->nslots;
2264 for (j = 0; j < nslots; ++j) {
2265 LLVMValueRef index [2], addr, daddr;
2266 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2268 if (ainfo->pair_storage [j] == LLVMArgNone)
2271 switch (ainfo->pair_storage [j]) {
2273 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2274 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2275 addr = LLVMBuildGEP (builder, address, index, 1, "");
2277 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2278 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2279 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2281 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2283 case LLVMArgInFPReg:
2284 if (ainfo->esize == 8)
2285 arg_type = LLVMDoubleType ();
2287 arg_type = LLVMFloatType ();
2288 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2289 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2290 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2291 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2296 g_assert_not_reached ();
2298 size -= sizeof (gpointer);
2305 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2308 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2309 * get executed every time control reaches them.
2311 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2313 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2314 return ctx->last_alloca;
2318 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2320 return build_alloca_llvm_type_name (ctx, t, align, "");
2324 build_alloca (EmitContext *ctx, MonoType *t)
2326 MonoClass *k = mono_class_from_mono_type (t);
2329 g_assert (!mini_is_gsharedvt_variable_type (t));
2331 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2334 align = mono_class_min_align (k);
2336 /* Sometimes align is not a power of 2 */
2337 while (mono_is_power_of_two (align) == -1)
2340 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2344 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2348 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2350 MonoCompile *cfg = ctx->cfg;
2351 LLVMBuilderRef builder = ctx->builder;
2352 LLVMValueRef offset, offset_var;
2353 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2354 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2358 g_assert (info_var);
2359 g_assert (locals_var);
2361 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2363 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2364 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2366 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2367 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2369 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2373 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2376 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2379 module->used = g_ptr_array_sized_new (16);
2380 g_ptr_array_add (module->used, global);
2384 emit_llvm_used (MonoLLVMModule *module)
2386 LLVMModuleRef lmodule = module->lmodule;
2387 LLVMTypeRef used_type;
2388 LLVMValueRef used, *used_elem;
2394 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2395 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2396 used_elem = g_new0 (LLVMValueRef, module->used->len);
2397 for (i = 0; i < module->used->len; ++i)
2398 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2399 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2400 LLVMSetLinkage (used, LLVMAppendingLinkage);
2401 LLVMSetSection (used, "llvm.metadata");
2407 * Emit a function mapping method indexes to their code
2410 emit_get_method (MonoLLVMModule *module)
2412 LLVMModuleRef lmodule = module->lmodule;
2413 LLVMValueRef func, switch_ins, m;
2414 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2415 LLVMBasicBlockRef *bbs;
2417 LLVMBuilderRef builder;
2422 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2423 * but generating code seems safer.
2425 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2426 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2427 LLVMSetLinkage (func, LLVMExternalLinkage);
2428 LLVMSetVisibility (func, LLVMHiddenVisibility);
2429 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2430 module->get_method = func;
2432 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2435 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2436 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2437 * then we will have to find another solution.
2440 name = g_strdup_printf ("BB_CODE_START");
2441 code_start_bb = LLVMAppendBasicBlock (func, name);
2443 builder = LLVMCreateBuilder ();
2444 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2445 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2447 name = g_strdup_printf ("BB_CODE_END");
2448 code_end_bb = LLVMAppendBasicBlock (func, name);
2450 builder = LLVMCreateBuilder ();
2451 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2452 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2454 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2455 for (i = 0; i < module->max_method_idx + 1; ++i) {
2456 name = g_strdup_printf ("BB_%d", i);
2457 bb = LLVMAppendBasicBlock (func, name);
2461 builder = LLVMCreateBuilder ();
2462 LLVMPositionBuilderAtEnd (builder, bb);
2464 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2466 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2468 LLVMBuildRet (builder, LLVMConstNull (rtype));
2471 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2472 builder = LLVMCreateBuilder ();
2473 LLVMPositionBuilderAtEnd (builder, fail_bb);
2474 LLVMBuildRet (builder, LLVMConstNull (rtype));
2476 builder = LLVMCreateBuilder ();
2477 LLVMPositionBuilderAtEnd (builder, entry_bb);
2479 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2481 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2482 for (i = 0; i < module->max_method_idx + 1; ++i) {
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2486 mark_as_used (module, func);
2490 * emit_get_unbox_tramp:
2492 * Emit a function mapping method indexes to their unbox trampoline
2495 emit_get_unbox_tramp (MonoLLVMModule *module)
2497 LLVMModuleRef lmodule = module->lmodule;
2498 LLVMValueRef func, switch_ins, m;
2499 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2500 LLVMBasicBlockRef *bbs;
2502 LLVMBuilderRef builder;
2506 /* Similar to emit_get_method () */
2508 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2509 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2510 LLVMSetLinkage (func, LLVMExternalLinkage);
2511 LLVMSetVisibility (func, LLVMHiddenVisibility);
2512 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2513 module->get_unbox_tramp = func;
2515 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2517 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2518 for (i = 0; i < module->max_method_idx + 1; ++i) {
2519 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2523 name = g_strdup_printf ("BB_%d", i);
2524 bb = LLVMAppendBasicBlock (func, name);
2528 builder = LLVMCreateBuilder ();
2529 LLVMPositionBuilderAtEnd (builder, bb);
2531 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2534 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, fail_bb);
2537 LLVMBuildRet (builder, LLVMConstNull (rtype));
2539 builder = LLVMCreateBuilder ();
2540 LLVMPositionBuilderAtEnd (builder, entry_bb);
2542 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2543 for (i = 0; i < module->max_method_idx + 1; ++i) {
2544 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2548 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2551 mark_as_used (module, func);
2554 /* Add a function to mark the beginning of LLVM code */
2556 emit_llvm_code_start (MonoLLVMModule *module)
2558 LLVMModuleRef lmodule = module->lmodule;
2560 LLVMBasicBlockRef entry_bb;
2561 LLVMBuilderRef builder;
2563 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2564 LLVMSetLinkage (func, LLVMInternalLinkage);
2565 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2566 module->code_start = func;
2567 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2568 builder = LLVMCreateBuilder ();
2569 LLVMPositionBuilderAtEnd (builder, entry_bb);
2570 LLVMBuildRetVoid (builder);
2574 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2576 LLVMModuleRef lmodule = module->lmodule;
2577 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2578 LLVMBasicBlockRef entry_bb;
2579 LLVMBuilderRef builder;
2586 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2587 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2596 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2597 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2600 g_assert_not_reached ();
2602 LLVMSetLinkage (func, LLVMInternalLinkage);
2603 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2604 mono_llvm_set_preserveall_cc (func);
2605 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2606 builder = LLVMCreateBuilder ();
2607 LLVMPositionBuilderAtEnd (builder, entry_bb);
2610 ji = g_new0 (MonoJumpInfo, 1);
2611 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2612 ji = mono_aot_patch_info_dup (ji);
2613 got_offset = mono_aot_get_got_offset (ji);
2614 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2616 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2617 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2618 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2619 args [1] = LLVMGetParam (func, 0);
2621 args [2] = LLVMGetParam (func, 1);
2623 ji = g_new0 (MonoJumpInfo, 1);
2624 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2625 ji->data.name = icall_name;
2626 ji = mono_aot_patch_info_dup (ji);
2627 got_offset = mono_aot_get_got_offset (ji);
2628 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2629 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2630 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2631 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2632 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2633 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2634 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2636 // Set the inited flag
2637 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2638 indexes [1] = LLVMGetParam (func, 0);
2639 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2641 LLVMBuildRetVoid (builder);
2643 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2648 * Emit wrappers around the C icalls used to initialize llvm methods, to
2649 * make the calling code smaller and to enable usage of the llvm
2650 * PreserveAll calling convention.
2653 emit_init_icall_wrappers (MonoLLVMModule *module)
2655 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2656 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2657 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2658 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2662 emit_llvm_code_end (MonoLLVMModule *module)
2664 LLVMModuleRef lmodule = module->lmodule;
2666 LLVMBasicBlockRef entry_bb;
2667 LLVMBuilderRef builder;
2669 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2670 LLVMSetLinkage (func, LLVMInternalLinkage);
2671 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2672 module->code_end = func;
2673 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2674 builder = LLVMCreateBuilder ();
2675 LLVMPositionBuilderAtEnd (builder, entry_bb);
2676 LLVMBuildRetVoid (builder);
2680 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2682 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2685 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2686 need_div_check = TRUE;
2688 if (!need_div_check)
2691 switch (ins->opcode) {
2704 case OP_IDIV_UN_IMM:
2705 case OP_LDIV_UN_IMM:
2706 case OP_IREM_UN_IMM:
2707 case OP_LREM_UN_IMM: {
2709 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2710 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2712 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2713 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2716 builder = ctx->builder;
2718 /* b == -1 && a == 0x80000000 */
2720 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2721 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2722 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2724 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2725 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2728 builder = ctx->builder;
2740 * Emit code to initialize the GOT slots used by the method.
2743 emit_init_method (EmitContext *ctx)
2745 LLVMValueRef indexes [16], args [16], callee;
2746 LLVMValueRef inited_var, cmp, call;
2747 LLVMBasicBlockRef inited_bb, notinited_bb;
2748 LLVMBuilderRef builder = ctx->builder;
2749 MonoCompile *cfg = ctx->cfg;
2751 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2753 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2754 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2755 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2757 args [0] = inited_var;
2758 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2759 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2761 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2763 inited_bb = ctx->inited_bb;
2764 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2766 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2768 builder = ctx->builder = create_builder (ctx);
2769 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2772 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2773 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2774 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2775 callee = ctx->module->init_method_gshared_mrgctx;
2776 call = LLVMBuildCall (builder, callee, args, 2, "");
2777 } else if (ctx->rgctx_arg) {
2778 /* A vtable is passed as the rgctx argument */
2779 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2780 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2781 callee = ctx->module->init_method_gshared_vtable;
2782 call = LLVMBuildCall (builder, callee, args, 2, "");
2783 } else if (cfg->gshared) {
2784 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2785 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2786 callee = ctx->module->init_method_gshared_this;
2787 call = LLVMBuildCall (builder, callee, args, 2, "");
2789 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2790 callee = ctx->module->init_method;
2791 call = LLVMBuildCall (builder, callee, args, 1, "");
2795 * This enables llvm to keep arguments in their original registers/
2796 * scratch registers, since the call will not clobber them.
2798 mono_llvm_set_call_preserveall_cc (call);
2800 LLVMBuildBr (builder, inited_bb);
2801 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2803 builder = ctx->builder = create_builder (ctx);
2804 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2808 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2811 * Emit unbox trampoline using a tail call
2813 LLVMValueRef tramp, call, *args;
2814 LLVMBuilderRef builder;
2815 LLVMBasicBlockRef lbb;
2816 LLVMCallInfo *linfo;
2820 tramp_name = g_strdup_printf ("ut_%s", method_name);
2821 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2822 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2823 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2824 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2826 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2827 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2828 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2829 if (ctx->cfg->vret_addr) {
2830 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2831 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2832 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2833 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2837 lbb = LLVMAppendBasicBlock (tramp, "");
2838 builder = LLVMCreateBuilder ();
2839 LLVMPositionBuilderAtEnd (builder, lbb);
2841 nargs = LLVMCountParamTypes (method_type);
2842 args = g_new0 (LLVMValueRef, nargs);
2843 for (i = 0; i < nargs; ++i) {
2844 args [i] = LLVMGetParam (tramp, i);
2845 if (i == ctx->this_arg_pindex) {
2846 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2848 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2849 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2850 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2853 call = LLVMBuildCall (builder, method, args, nargs, "");
2854 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2855 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2856 if (linfo->ret.storage == LLVMArgVtypeByRef)
2857 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2859 // FIXME: This causes assertions in clang
2860 //mono_llvm_set_must_tail (call);
2861 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2862 LLVMBuildRetVoid (builder);
2864 LLVMBuildRet (builder, call);
2866 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2872 * Emit code to load/convert arguments.
2875 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2878 MonoCompile *cfg = ctx->cfg;
2879 MonoMethodSignature *sig = ctx->sig;
2880 LLVMCallInfo *linfo = ctx->linfo;
2884 LLVMBuilderRef old_builder = ctx->builder;
2885 ctx->builder = builder;
2887 ctx->alloca_builder = create_builder (ctx);
2890 * Handle indirect/volatile variables by allocating memory for them
2891 * using 'alloca', and storing their address in a temporary.
2893 for (i = 0; i < cfg->num_varinfo; ++i) {
2894 MonoInst *var = cfg->varinfo [i];
2897 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2898 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2899 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2902 /* Could be already created by an OP_VPHI */
2903 if (!ctx->addresses [var->dreg]) {
2904 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2905 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2907 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2911 names = g_new (char *, sig->param_count);
2912 mono_method_get_param_names (cfg->method, (const char **) names);
2914 for (i = 0; i < sig->param_count; ++i) {
2915 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2916 int reg = cfg->args [i + sig->hasthis]->dreg;
2919 pindex = ainfo->pindex;
2921 switch (ainfo->storage) {
2922 case LLVMArgVtypeInReg:
2923 case LLVMArgAsFpArgs: {
2924 LLVMValueRef args [8];
2927 pindex += ainfo->ndummy_fpargs;
2929 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2930 memset (args, 0, sizeof (args));
2931 if (ainfo->storage == LLVMArgVtypeInReg) {
2932 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2933 if (ainfo->pair_storage [1] != LLVMArgNone)
2934 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2936 g_assert (ainfo->nslots <= 8);
2937 for (j = 0; j < ainfo->nslots; ++j)
2938 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2940 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2942 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2944 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2945 /* Treat these as normal values */
2946 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2950 case LLVMArgVtypeByVal: {
2951 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2953 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2954 /* Treat these as normal values */
2955 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2959 case LLVMArgVtypeByRef: {
2960 /* The argument is passed by ref */
2961 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2964 case LLVMArgAsIArgs: {
2965 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2968 /* The argument is received as an array of ints, store it into the real argument */
2969 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2971 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2972 if (size < SIZEOF_VOID_P) {
2973 /* The upper bits of the registers might not be valid */
2974 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2975 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2976 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2978 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2982 case LLVMArgVtypeAsScalar:
2983 g_assert_not_reached ();
2985 case LLVMArgGsharedvtFixed: {
2986 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2987 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2990 name = g_strdup_printf ("arg_%s", names [i]);
2992 name = g_strdup_printf ("arg_%d", i);
2994 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2997 case LLVMArgGsharedvtFixedVtype: {
2998 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3001 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3003 name = g_strdup_printf ("vtype_arg_%d", i);
3005 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3006 g_assert (ctx->addresses [reg]);
3007 LLVMSetValueName (ctx->addresses [reg], name);
3008 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3011 case LLVMArgGsharedvtVariable:
3012 /* The IR treats these as variables with addresses */
3013 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3016 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3023 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3025 emit_volatile_store (ctx, cfg->args [0]->dreg);
3026 for (i = 0; i < sig->param_count; ++i)
3027 if (!mini_type_is_vtype (sig->params [i]))
3028 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3030 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3031 LLVMValueRef this_alloc;
3034 * The exception handling code needs the location where the this argument was
3035 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3036 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3037 * location into the LSDA.
3039 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3040 /* This volatile store will keep the alloca alive */
3041 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3043 set_metadata_flag (this_alloc, "mono.this");
3046 if (cfg->rgctx_var) {
3047 LLVMValueRef rgctx_alloc, store;
3050 * We handle the rgctx arg similarly to the this pointer.
3052 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3053 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3054 /* This volatile store will keep the alloca alive */
3055 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3057 set_metadata_flag (rgctx_alloc, "mono.this");
3060 /* Initialize the method if needed */
3061 if (cfg->compile_aot && ctx->llvm_only) {
3062 /* Emit a location for the initialization code */
3063 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3064 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3066 LLVMBuildBr (ctx->builder, ctx->init_bb);
3067 builder = ctx->builder = create_builder (ctx);
3068 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3069 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3072 /* Compute nesting between clauses */
3073 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3074 for (i = 0; i < cfg->header->num_clauses; ++i) {
3075 for (j = 0; j < cfg->header->num_clauses; ++j) {
3076 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3077 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3079 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3080 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3085 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3086 * it needs to continue normally, or return back to the exception handling system.
3088 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3092 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3095 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3096 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3097 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3099 if (bb->in_scount == 0) {
3102 sprintf (name, "finally_ind_bb%d", bb->block_num);
3103 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3104 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3106 ctx->bblocks [bb->block_num].finally_ind = val;
3108 /* Create a variable to hold the exception var */
3110 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3114 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3115 * LLVM bblock containing a landing pad causes problems for the
3116 * LLVM optimizer passes.
3118 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3119 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3121 ctx->builder = old_builder;
3125 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3127 MonoCompile *cfg = ctx->cfg;
3128 LLVMValueRef *values = ctx->values;
3129 LLVMValueRef *addresses = ctx->addresses;
3130 MonoCallInst *call = (MonoCallInst*)ins;
3131 MonoMethodSignature *sig = call->signature;
3132 LLVMValueRef callee = NULL, lcall;
3134 LLVMCallInfo *cinfo;
3138 LLVMTypeRef llvm_sig;
3140 gboolean is_virtual, calli, preserveall;
3141 LLVMBuilderRef builder = *builder_ref;
3143 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3144 set_failure (ctx, "non-default callconv");
3148 cinfo = call->cinfo;
3150 if (call->rgctx_arg_reg)
3151 cinfo->rgctx_arg = TRUE;
3152 if (call->imt_arg_reg)
3153 cinfo->imt_arg = TRUE;
3155 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3157 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3161 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3162 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3164 preserveall = FALSE;
3166 /* FIXME: Avoid creating duplicate methods */
3168 if (ins->flags & MONO_INST_HAS_METHOD) {
3172 if (cfg->compile_aot) {
3173 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3175 set_failure (ctx, "can't encode patch");
3178 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3180 * Collect instructions representing the callee into a hash so they can be replaced
3181 * by the llvm method for the callee if the callee turns out to be direct
3182 * callable. Currently this only requires it to not fail llvm compilation.
3184 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3185 l = g_slist_prepend (l, callee);
3186 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3190 static int tramp_index;
3193 name = g_strdup_printf ("tramp_%d", tramp_index);
3196 #if LLVM_API_VERSION > 100
3198 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3199 * Make all calls through a global. The address of the global will be saved in
3200 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3203 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3206 mono_create_jit_trampoline (mono_domain_get (),
3207 call->method, &error);
3208 if (!mono_error_ok (&error))
3209 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3210 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3211 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3212 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3213 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3215 callee = LLVMBuildLoad (builder, tramp_var, "");
3218 mono_create_jit_trampoline (mono_domain_get (),
3219 call->method, &error);
3220 if (!mono_error_ok (&error))
3221 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3223 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3226 if (!mono_error_ok (&error))
3227 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3228 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3233 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3234 /* LLVM miscompiles async methods */
3235 set_failure (ctx, "#13734");
3240 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3246 memset (&ji, 0, sizeof (ji));
3247 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3248 ji.data.target = info->name;
3250 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3252 if (cfg->compile_aot) {
3253 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3255 set_failure (ctx, "can't encode patch");
3259 target = (gpointer)mono_icall_get_wrapper (info);
3260 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3263 if (cfg->compile_aot) {
3265 if (cfg->abs_patches) {
3266 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3268 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3270 set_failure (ctx, "can't encode patch");
3276 set_failure (ctx, "aot");
3280 #if LLVM_API_VERSION > 100
3281 if (cfg->abs_patches) {
3282 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3286 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3287 mono_error_assert_ok (&error);
3288 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3290 g_assert_not_reached ();
3293 g_assert_not_reached ();
3296 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3298 if (cfg->abs_patches) {
3299 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3304 * FIXME: Some trampolines might have
3305 * their own calling convention on some platforms.
3307 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3308 mono_error_assert_ok (&error);
3309 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3313 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3320 int size = sizeof (gpointer);
3323 g_assert (ins->inst_offset % size == 0);
3324 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3326 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3328 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3330 if (ins->flags & MONO_INST_HAS_METHOD) {
3335 * Collect and convert arguments
3337 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3338 len = sizeof (LLVMValueRef) * nargs;
3339 args = (LLVMValueRef*)alloca (len);
3340 memset (args, 0, len);
3341 l = call->out_ireg_args;
3343 if (call->rgctx_arg_reg) {
3344 g_assert (values [call->rgctx_arg_reg]);
3345 g_assert (cinfo->rgctx_arg_pindex < nargs);
3347 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3348 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3349 * it using a volatile load.
3352 if (!ctx->imt_rgctx_loc)
3353 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3354 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3355 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3357 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3360 if (call->imt_arg_reg) {
3361 g_assert (!ctx->llvm_only);
3362 g_assert (values [call->imt_arg_reg]);
3363 g_assert (cinfo->imt_arg_pindex < nargs);
3365 if (!ctx->imt_rgctx_loc)
3366 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3367 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3368 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3370 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3373 switch (cinfo->ret.storage) {
3374 case LLVMArgGsharedvtVariable: {
3375 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3377 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3378 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3380 g_assert (addresses [call->inst.dreg]);
3381 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3387 if (!addresses [call->inst.dreg])
3388 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3389 g_assert (cinfo->vret_arg_pindex < nargs);
3390 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3391 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3393 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3399 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3400 * use the real callee for argument type conversion.
3402 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3403 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3404 LLVMGetParamTypes (callee_type, param_types);
3406 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3409 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3411 pindex = ainfo->pindex;
3413 regpair = (guint32)(gssize)(l->data);
3414 reg = regpair & 0xffffff;
3415 args [pindex] = values [reg];
3416 switch (ainfo->storage) {
3417 case LLVMArgVtypeInReg:
3418 case LLVMArgAsFpArgs: {
3422 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3423 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3424 pindex += ainfo->ndummy_fpargs;
3426 g_assert (addresses [reg]);
3427 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3431 // FIXME: Get rid of the VMOVE
3434 case LLVMArgVtypeByVal:
3435 g_assert (addresses [reg]);
3436 args [pindex] = addresses [reg];
3438 case LLVMArgVtypeByRef: {
3439 g_assert (addresses [reg]);
3440 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3443 case LLVMArgAsIArgs:
3444 g_assert (addresses [reg]);
3445 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3447 case LLVMArgVtypeAsScalar:
3448 g_assert_not_reached ();
3450 case LLVMArgGsharedvtFixed:
3451 case LLVMArgGsharedvtFixedVtype:
3452 g_assert (addresses [reg]);
3453 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3455 case LLVMArgGsharedvtVariable:
3456 g_assert (addresses [reg]);
3457 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3460 g_assert (args [pindex]);
3461 if (i == 0 && sig->hasthis)
3462 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3464 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3467 g_assert (pindex <= nargs);
3472 // FIXME: Align call sites
3478 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3481 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3483 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3484 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3486 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3487 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3488 if (!sig->pinvoke && !cfg->llvm_only)
3489 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3491 mono_llvm_set_call_preserveall_cc (lcall);
3493 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3494 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3495 if (!ctx->llvm_only && call->rgctx_arg_reg)
3496 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3497 if (call->imt_arg_reg)
3498 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3500 /* Add byval attributes if needed */
3501 for (i = 0; i < sig->param_count; ++i) {
3502 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3504 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3505 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3509 * Convert the result
3511 switch (cinfo->ret.storage) {
3512 case LLVMArgVtypeInReg: {
3513 LLVMValueRef regs [2];
3515 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3519 if (!addresses [ins->dreg])
3520 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3522 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3523 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3524 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3525 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3528 case LLVMArgVtypeByVal:
3529 if (!addresses [call->inst.dreg])
3530 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3531 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3533 case LLVMArgFpStruct:
3534 if (!addresses [call->inst.dreg])
3535 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3536 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3538 case LLVMArgVtypeAsScalar:
3539 if (!addresses [call->inst.dreg])
3540 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3541 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3543 case LLVMArgVtypeRetAddr:
3544 case LLVMArgVtypeByRef:
3545 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3546 /* Some opcodes like STOREX_MEMBASE access these by value */
3547 g_assert (addresses [call->inst.dreg]);
3548 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3551 case LLVMArgGsharedvtVariable:
3553 case LLVMArgGsharedvtFixed:
3554 case LLVMArgGsharedvtFixedVtype:
3555 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3558 if (sig->ret->type != MONO_TYPE_VOID)
3559 /* If the method returns an unsigned value, need to zext it */
3560 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
3564 *builder_ref = ctx->builder;
3568 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3570 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3571 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3573 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3576 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3578 if (ctx->cfg->compile_aot) {
3579 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3581 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3582 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3583 mono_memory_barrier ();
3586 ctx->module->rethrow = callee;
3588 ctx->module->throw_icall = callee;
3592 LLVMValueRef args [2];
3594 args [0] = convert (ctx, exc, exc_type);
3595 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3597 LLVMBuildUnreachable (ctx->builder);
3599 ctx->builder = create_builder (ctx);
3603 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3605 MonoMethodSignature *throw_sig;
3606 LLVMValueRef callee, arg;
3607 const char *icall_name;
3609 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3610 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3613 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3614 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3615 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3616 if (ctx->cfg->compile_aot) {
3617 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3622 * LLVM doesn't push the exception argument, so we need a different
3625 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3627 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3629 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3632 mono_memory_barrier ();
3633 #if LLVM_API_VERSION < 100
3635 ctx->module->rethrow = callee;
3637 ctx->module->throw_icall = callee;
3640 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3641 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3645 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3647 const char *icall_name = "mono_llvm_resume_exception";
3648 LLVMValueRef callee = ctx->module->resume_eh;
3650 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3653 if (ctx->cfg->compile_aot) {
3654 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3656 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3657 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3658 mono_memory_barrier ();
3660 ctx->module->resume_eh = callee;
3664 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3666 LLVMBuildUnreachable (ctx->builder);
3668 ctx->builder = create_builder (ctx);
3672 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3674 const char *icall_name = "mono_llvm_clear_exception";
3676 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3677 LLVMValueRef callee = NULL;
3680 if (ctx->cfg->compile_aot) {
3681 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3683 // FIXME: This is broken.
3684 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3688 g_assert (builder && callee);
3690 return LLVMBuildCall (builder, callee, NULL, 0, "");
3694 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3696 const char *icall_name = "mono_llvm_load_exception";
3698 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3699 LLVMValueRef callee = NULL;
3702 if (ctx->cfg->compile_aot) {
3703 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3705 // FIXME: This is broken.
3706 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3710 g_assert (builder && callee);
3712 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3717 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3719 const char *icall_name = "mono_llvm_match_exception";
3721 ctx->builder = builder;
3723 const int num_args = 5;
3724 LLVMValueRef args [num_args];
3725 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3726 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3727 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3728 if (ctx->cfg->rgctx_var) {
3729 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3730 g_assert (rgctx_alloc);
3731 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3733 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3736 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3738 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3740 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3741 LLVMValueRef callee = ctx->module->match_exc;
3744 if (ctx->cfg->compile_aot) {
3745 ctx->builder = builder;
3746 // get_callee expects ctx->builder to be the emitting builder
3747 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3749 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3750 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3751 ctx->module->match_exc = callee;
3752 mono_memory_barrier ();
3756 g_assert (builder && callee);
3758 g_assert (ctx->ex_var);
3760 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3763 // FIXME: This won't work because the code-finding makes this
3765 /*#define MONO_PERSONALITY_DEBUG*/
3767 #ifdef MONO_PERSONALITY_DEBUG
3768 static const gboolean use_debug_personality = TRUE;
3769 static const char *default_personality_name = "mono_debug_personality";
3771 static const gboolean use_debug_personality = FALSE;
3772 static const char *default_personality_name = "__gxx_personality_v0";
3776 default_cpp_lpad_exc_signature (void)
3778 static gboolean inited = FALSE;
3779 static LLVMTypeRef sig;
3782 LLVMTypeRef signature [2];
3783 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3784 signature [1] = LLVMInt32Type ();
3785 sig = LLVMStructType (signature, 2, FALSE);
3793 get_mono_personality (EmitContext *ctx)
3795 LLVMValueRef personality = NULL;
3796 static gint32 mapping_inited = FALSE;
3797 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3799 if (!use_debug_personality) {
3800 if (ctx->cfg->compile_aot) {
3801 personality = get_intrinsic (ctx, default_personality_name);
3802 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3803 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3804 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3807 if (ctx->cfg->compile_aot) {
3808 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3810 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3811 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3812 mono_memory_barrier ();
3816 g_assert (personality);
3820 static LLVMBasicBlockRef
3821 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3823 MonoCompile *cfg = ctx->cfg;
3824 LLVMBuilderRef old_builder = ctx->builder;
3825 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3827 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3828 ctx->builder = lpadBuilder;
3830 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3831 g_assert (handler_bb);
3833 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3834 LLVMValueRef personality = get_mono_personality (ctx);
3835 g_assert (personality);
3837 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3838 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3840 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3841 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3842 g_assert (landing_pad);
3844 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3845 LLVMAddClause (landing_pad, cast);
3847 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3848 LLVMBuilderRef resume_builder = create_builder (ctx);
3849 ctx->builder = resume_builder;
3850 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3852 emit_resume_eh (ctx, handler_bb);
3855 ctx->builder = lpadBuilder;
3856 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3858 gboolean finally_only = TRUE;
3860 MonoExceptionClause *group_cursor = group_start;
3862 for (int i = 0; i < group_size; i ++) {
3863 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3864 finally_only = FALSE;
3870 // Handle landing pad inlining
3872 if (!finally_only) {
3873 // So at each level of the exception stack we will match the exception again.
3874 // During that match, we need to compare against the handler types for the current
3875 // protected region. We send the try start and end so that we can only check against
3876 // handlers for this lexical protected region.
3877 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3879 // if returns -1, resume
3880 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3882 // else move to that target bb
3883 for (int i=0; i < group_size; i++) {
3884 MonoExceptionClause *clause = group_start + i;
3885 int clause_index = clause - cfg->header->clauses;
3886 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3887 g_assert (handler_bb);
3888 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3889 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3892 int clause_index = group_start - cfg->header->clauses;
3893 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3894 g_assert (finally_bb);
3896 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3899 ctx->builder = old_builder;
3906 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3908 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3909 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3911 // Make exception available to catch blocks
3912 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3913 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3915 g_assert (ctx->ex_var);
3916 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3918 if (bb->in_scount == 1) {
3919 MonoInst *exvar = bb->in_stack [0];
3920 g_assert (!ctx->values [exvar->dreg]);
3921 g_assert (ctx->ex_var);
3922 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3923 emit_volatile_store (ctx, exvar->dreg);
3926 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3929 LLVMBuilderRef handler_builder = create_builder (ctx);
3930 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3931 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3933 // Make the handler code end with a jump to cbb
3934 LLVMBuildBr (handler_builder, cbb);
3938 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3940 MonoCompile *cfg = ctx->cfg;
3941 LLVMValueRef *values = ctx->values;
3942 LLVMModuleRef lmodule = ctx->lmodule;
3943 BBInfo *bblocks = ctx->bblocks;
3945 LLVMValueRef personality;
3946 LLVMValueRef landing_pad;
3947 LLVMBasicBlockRef target_bb;
3949 static int ti_generator;
3951 LLVMValueRef type_info;
3955 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3957 if (cfg->compile_aot) {
3958 /* Use a dummy personality function */
3959 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3960 g_assert (personality);
3962 #if LLVM_API_VERSION > 100
3963 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3964 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3965 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3966 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3967 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3968 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3969 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3971 static gint32 mapping_inited;
3973 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3975 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3976 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3980 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3982 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3985 * Create the type info
3987 sprintf (ti_name, "type_info_%d", ti_generator);
3990 if (cfg->compile_aot) {
3991 /* decode_eh_frame () in aot-runtime.c will decode this */
3992 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3993 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3996 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3998 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4000 #if LLVM_API_VERSION > 100
4001 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4002 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4007 * After the cfg mempool is freed, the type info will point to stale memory,
4008 * but this is not a problem, since we decode it once in exception_cb during
4011 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4012 *(gint32*)ti = clause_index;
4014 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4016 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4021 LLVMTypeRef members [2], ret_type;
4023 members [0] = i8ptr;
4024 members [1] = LLVMInt32Type ();
4025 ret_type = LLVMStructType (members, 2, FALSE);
4027 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4028 LLVMAddClause (landing_pad, type_info);
4030 /* Store the exception into the exvar */
4032 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4036 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4037 * code expects control to be transferred to this landing pad even in the
4038 * presence of nested clauses. The landing pad needs to branch to the landing
4039 * pads belonging to nested clauses based on the selector value returned by
4040 * the landing pad instruction, which is passed to the landing pad in a
4041 * register by the EH code.
4043 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4044 g_assert (target_bb);
4047 * Branch to the correct landing pad
4049 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4050 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4052 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4053 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4054 MonoBasicBlock *handler_bb;
4056 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4057 g_assert (handler_bb);
4059 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4060 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4063 /* Start a new bblock which CALL_HANDLER can branch to */
4064 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4066 ctx->builder = builder = create_builder (ctx);
4067 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4069 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4071 /* Store the exception into the IL level exvar */
4072 if (bb->in_scount == 1) {
4073 g_assert (bb->in_scount == 1);
4074 exvar = bb->in_stack [0];
4076 // FIXME: This is shared with filter clauses ?
4077 g_assert (!values [exvar->dreg]);
4079 g_assert (ctx->ex_var);
4080 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4081 emit_volatile_store (ctx, exvar->dreg);
4087 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4089 MonoCompile *cfg = ctx->cfg;
4090 MonoMethodSignature *sig = ctx->sig;
4091 LLVMValueRef method = ctx->lmethod;
4092 LLVMValueRef *values = ctx->values;
4093 LLVMValueRef *addresses = ctx->addresses;
4094 LLVMCallInfo *linfo = ctx->linfo;
4095 BBInfo *bblocks = ctx->bblocks;
4097 LLVMBasicBlockRef cbb;
4098 LLVMBuilderRef builder, starting_builder;
4099 gboolean has_terminator;
4101 LLVMValueRef lhs, rhs;
4104 cbb = get_end_bb (ctx, bb);
4106 builder = create_builder (ctx);
4107 ctx->builder = builder;
4108 LLVMPositionBuilderAtEnd (builder, cbb);
4113 if (bb->flags & BB_EXCEPTION_HANDLER) {
4114 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4115 set_failure (ctx, "handler without invokes");
4120 emit_llvmonly_handler_start (ctx, bb, cbb);
4122 emit_handler_start (ctx, bb, builder);
4125 builder = ctx->builder;
4128 has_terminator = FALSE;
4129 starting_builder = builder;
4130 for (ins = bb->code; ins; ins = ins->next) {
4131 const char *spec = LLVM_INS_INFO (ins->opcode);
4133 char dname_buf [128];
4135 emit_dbg_loc (ctx, builder, ins->cil_code);
4140 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4141 * Start a new bblock. If the llvm optimization passes merge these, we
4142 * can work around that by doing a volatile load + cond branch from
4143 * localloc-ed memory.
4145 //set_failure (ctx, "basic block too long");
4146 cbb = gen_bb (ctx, "CONT_LONG_BB");
4147 LLVMBuildBr (ctx->builder, cbb);
4148 ctx->builder = builder = create_builder (ctx);
4149 LLVMPositionBuilderAtEnd (builder, cbb);
4150 ctx->bblocks [bb->block_num].end_bblock = cbb;
4155 /* There could be instructions after a terminator, skip them */
4158 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4159 sprintf (dname_buf, "t%d", ins->dreg);
4163 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4164 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4166 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4167 lhs = emit_volatile_load (ctx, ins->sreg1);
4169 /* It is ok for SETRET to have an uninitialized argument */
4170 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4171 set_failure (ctx, "sreg1");
4174 lhs = values [ins->sreg1];
4180 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4181 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4182 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4183 rhs = emit_volatile_load (ctx, ins->sreg2);
4185 if (!values [ins->sreg2]) {
4186 set_failure (ctx, "sreg2");
4189 rhs = values [ins->sreg2];
4195 //mono_print_ins (ins);
4196 switch (ins->opcode) {
4199 case OP_LIVERANGE_START:
4200 case OP_LIVERANGE_END:
4203 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4206 #if SIZEOF_VOID_P == 4
4207 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4209 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4213 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4217 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4219 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4221 case OP_DUMMY_ICONST:
4222 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4224 case OP_DUMMY_I8CONST:
4225 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4227 case OP_DUMMY_R8CONST:
4228 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4231 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4232 LLVMBuildBr (builder, target_bb);
4233 has_terminator = TRUE;
4240 LLVMBasicBlockRef new_bb;
4241 LLVMBuilderRef new_builder;
4243 // The default branch is already handled
4244 // FIXME: Handle it here
4246 /* Start new bblock */
4247 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4248 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4250 lhs = convert (ctx, lhs, LLVMInt32Type ());
4251 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4252 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4253 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4255 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4258 new_builder = create_builder (ctx);
4259 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4260 LLVMBuildUnreachable (new_builder);
4262 has_terminator = TRUE;
4263 g_assert (!ins->next);
4269 switch (linfo->ret.storage) {
4270 case LLVMArgVtypeInReg: {
4271 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4272 LLVMValueRef val, addr, retval;
4275 retval = LLVMGetUndef (ret_type);
4277 if (!addresses [ins->sreg1]) {
4279 * The return type is an LLVM vector type, have to convert between it and the
4280 * real return type which is a struct type.
4282 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4283 /* Convert to 2xi64 first */
4284 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4286 for (i = 0; i < 2; ++i) {
4287 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4288 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4290 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4294 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4295 for (i = 0; i < 2; ++i) {
4296 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4297 LLVMValueRef indexes [2], part_addr;
4299 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4300 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4301 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4303 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4305 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4309 LLVMBuildRet (builder, retval);
4312 case LLVMArgVtypeAsScalar: {
4313 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4314 LLVMValueRef retval;
4316 g_assert (addresses [ins->sreg1]);
4318 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4319 LLVMBuildRet (builder, retval);
4322 case LLVMArgVtypeByVal: {
4323 LLVMValueRef retval;
4325 g_assert (addresses [ins->sreg1]);
4326 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4327 LLVMBuildRet (builder, retval);
4330 case LLVMArgVtypeByRef: {
4331 LLVMBuildRetVoid (builder);
4334 case LLVMArgGsharedvtFixed: {
4335 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4336 /* The return value is in lhs, need to store to the vret argument */
4337 /* sreg1 might not be set */
4339 g_assert (cfg->vret_addr);
4340 g_assert (values [cfg->vret_addr->dreg]);
4341 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4343 LLVMBuildRetVoid (builder);
4346 case LLVMArgGsharedvtFixedVtype: {
4348 LLVMBuildRetVoid (builder);
4351 case LLVMArgGsharedvtVariable: {
4353 LLVMBuildRetVoid (builder);
4356 case LLVMArgVtypeRetAddr: {
4357 LLVMBuildRetVoid (builder);
4360 case LLVMArgFpStruct: {
4361 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4362 LLVMValueRef retval;
4364 g_assert (addresses [ins->sreg1]);
4365 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4366 LLVMBuildRet (builder, retval);
4370 case LLVMArgNormal: {
4371 if (!lhs || ctx->is_dead [ins->sreg1]) {
4373 * The method did not set its return value, probably because it
4374 * ends with a throw.
4377 LLVMBuildRetVoid (builder);
4379 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4381 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4383 has_terminator = TRUE;
4387 g_assert_not_reached ();
4396 case OP_ICOMPARE_IMM:
4397 case OP_LCOMPARE_IMM:
4398 case OP_COMPARE_IMM: {
4400 LLVMValueRef cmp, args [16];
4401 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4403 if (ins->next->opcode == OP_NOP)
4406 if (ins->next->opcode == OP_BR)
4407 /* The comparison result is not needed */
4410 rel = mono_opcode_to_cond (ins->next->opcode);
4412 if (ins->opcode == OP_ICOMPARE_IMM) {
4413 lhs = convert (ctx, lhs, LLVMInt32Type ());
4414 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4416 if (ins->opcode == OP_LCOMPARE_IMM) {
4417 lhs = convert (ctx, lhs, LLVMInt64Type ());
4418 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4420 if (ins->opcode == OP_LCOMPARE) {
4421 lhs = convert (ctx, lhs, LLVMInt64Type ());
4422 rhs = convert (ctx, rhs, LLVMInt64Type ());
4424 if (ins->opcode == OP_ICOMPARE) {
4425 lhs = convert (ctx, lhs, LLVMInt32Type ());
4426 rhs = convert (ctx, rhs, LLVMInt32Type ());
4430 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4431 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4432 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4433 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4436 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4437 if (ins->opcode == OP_FCOMPARE) {
4438 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4439 } else if (ins->opcode == OP_RCOMPARE) {
4440 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4441 } else if (ins->opcode == OP_COMPARE_IMM) {
4442 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4443 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4445 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4446 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4447 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4448 /* The immediate is encoded in two fields */
4449 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4450 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4452 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4455 else if (ins->opcode == OP_COMPARE) {
4456 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4457 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4459 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4461 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4465 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4466 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4469 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4470 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4472 * If the target bb contains PHI instructions, LLVM requires
4473 * two PHI entries for this bblock, while we only generate one.
4474 * So convert this to an unconditional bblock. (bxc #171).
4476 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4478 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4480 has_terminator = TRUE;
4481 } else if (MONO_IS_SETCC (ins->next)) {
4482 sprintf (dname_buf, "t%d", ins->next->dreg);
4484 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4486 /* Add stores for volatile variables */
4487 emit_volatile_store (ctx, ins->next->dreg);
4488 } else if (MONO_IS_COND_EXC (ins->next)) {
4489 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4492 builder = ctx->builder;
4494 set_failure (ctx, "next");
4512 rel = mono_opcode_to_cond (ins->opcode);
4514 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4515 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4526 rel = mono_opcode_to_cond (ins->opcode);
4528 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4529 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4537 gboolean empty = TRUE;
4539 /* Check that all input bblocks really branch to us */
4540 for (i = 0; i < bb->in_count; ++i) {
4541 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4542 ins->inst_phi_args [i + 1] = -1;
4548 /* LLVM doesn't like phi instructions with zero operands */
4549 ctx->is_dead [ins->dreg] = TRUE;
4553 /* Created earlier, insert it now */
4554 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4556 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4557 int sreg1 = ins->inst_phi_args [i + 1];
4561 * Count the number of times the incoming bblock branches to us,
4562 * since llvm requires a separate entry for each.
4564 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4565 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4568 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4569 if (switch_ins->inst_many_bb [j] == bb)
4576 /* Remember for later */
4577 for (j = 0; j < count; ++j) {
4578 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4581 node->in_bb = bb->in_bb [i];
4583 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);
4593 values [ins->dreg] = lhs;
4597 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4600 values [ins->dreg] = lhs;
4602 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4604 * This is added by the spilling pass in case of the JIT,
4605 * but we have to do it ourselves.
4607 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4611 case OP_MOVE_F_TO_I4: {
4612 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4615 case OP_MOVE_I4_TO_F: {
4616 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4619 case OP_MOVE_F_TO_I8: {
4620 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4623 case OP_MOVE_I8_TO_F: {
4624 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4657 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4658 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4660 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4663 builder = ctx->builder;
4665 switch (ins->opcode) {
4668 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4672 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4676 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4680 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4684 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4688 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4692 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4696 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4700 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4704 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4708 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4712 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4716 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4720 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4724 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4727 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4730 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4734 g_assert_not_reached ();
4741 lhs = convert (ctx, lhs, LLVMFloatType ());
4742 rhs = convert (ctx, rhs, LLVMFloatType ());
4743 switch (ins->opcode) {
4745 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4748 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4751 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4754 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4757 g_assert_not_reached ();
4766 case OP_IREM_UN_IMM:
4768 case OP_IDIV_UN_IMM:
4774 case OP_ISHR_UN_IMM:
4784 case OP_LSHR_UN_IMM:
4790 case OP_SHR_UN_IMM: {
4793 if (spec [MONO_INST_SRC1] == 'l') {
4794 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4796 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4799 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4802 builder = ctx->builder;
4804 #if SIZEOF_VOID_P == 4
4805 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4806 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4809 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4810 lhs = convert (ctx, lhs, IntPtrType ());
4811 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4812 switch (ins->opcode) {
4816 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4820 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4825 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4829 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4831 case OP_IDIV_UN_IMM:
4832 case OP_LDIV_UN_IMM:
4833 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4837 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4839 case OP_IREM_UN_IMM:
4840 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4845 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4849 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4853 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4858 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4863 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4865 case OP_ISHR_UN_IMM:
4866 /* This is used to implement conv.u4, so the lhs could be an i8 */
4867 lhs = convert (ctx, lhs, LLVMInt32Type ());
4868 imm = convert (ctx, imm, LLVMInt32Type ());
4869 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4871 case OP_LSHR_UN_IMM:
4873 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4876 g_assert_not_reached ();
4881 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4884 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4887 lhs = convert (ctx, lhs, LLVMDoubleType ());
4888 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4891 lhs = convert (ctx, lhs, LLVMFloatType ());
4892 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4895 guint32 v = 0xffffffff;
4896 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4900 guint64 v = 0xffffffffffffffffLL;
4901 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4904 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4906 LLVMValueRef v1, v2;
4908 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4909 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4910 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4915 case OP_ICONV_TO_I1:
4916 case OP_ICONV_TO_I2:
4917 case OP_ICONV_TO_I4:
4918 case OP_ICONV_TO_U1:
4919 case OP_ICONV_TO_U2:
4920 case OP_ICONV_TO_U4:
4921 case OP_LCONV_TO_I1:
4922 case OP_LCONV_TO_I2:
4923 case OP_LCONV_TO_U1:
4924 case OP_LCONV_TO_U2:
4925 case OP_LCONV_TO_U4: {
4928 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);
4930 /* Have to do two casts since our vregs have type int */
4931 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4933 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4935 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4938 case OP_ICONV_TO_I8:
4939 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4941 case OP_ICONV_TO_U8:
4942 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4944 case OP_FCONV_TO_I4:
4945 case OP_RCONV_TO_I4:
4946 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4948 case OP_FCONV_TO_I1:
4949 case OP_RCONV_TO_I1:
4950 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4952 case OP_FCONV_TO_U1:
4953 case OP_RCONV_TO_U1:
4954 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4956 case OP_FCONV_TO_I2:
4957 case OP_RCONV_TO_I2:
4958 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4960 case OP_FCONV_TO_U2:
4961 case OP_RCONV_TO_U2:
4962 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4964 case OP_RCONV_TO_U4:
4965 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4967 case OP_FCONV_TO_I8:
4968 case OP_RCONV_TO_I8:
4969 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4972 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4974 case OP_ICONV_TO_R8:
4975 case OP_LCONV_TO_R8:
4976 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4978 case OP_ICONV_TO_R_UN:
4979 case OP_LCONV_TO_R_UN:
4980 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4982 #if SIZEOF_VOID_P == 4
4985 case OP_LCONV_TO_I4:
4986 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4988 case OP_ICONV_TO_R4:
4989 case OP_LCONV_TO_R4:
4990 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4992 values [ins->dreg] = v;
4994 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4996 case OP_FCONV_TO_R4:
4997 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4999 values [ins->dreg] = v;
5001 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5003 case OP_RCONV_TO_R8:
5004 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5006 case OP_RCONV_TO_R4:
5007 values [ins->dreg] = lhs;
5010 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5013 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5016 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5018 case OP_LOCALLOC_IMM: {
5021 guint32 size = ins->inst_imm;
5022 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5024 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5026 if (ins->flags & MONO_INST_INIT) {
5027 LLVMValueRef args [5];
5030 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5031 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5032 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5033 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5034 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5037 values [ins->dreg] = v;
5041 LLVMValueRef v, size;
5043 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
5045 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5047 if (ins->flags & MONO_INST_INIT) {
5048 LLVMValueRef args [5];
5051 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5053 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5054 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5055 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5057 values [ins->dreg] = v;
5061 case OP_LOADI1_MEMBASE:
5062 case OP_LOADU1_MEMBASE:
5063 case OP_LOADI2_MEMBASE:
5064 case OP_LOADU2_MEMBASE:
5065 case OP_LOADI4_MEMBASE:
5066 case OP_LOADU4_MEMBASE:
5067 case OP_LOADI8_MEMBASE:
5068 case OP_LOADR4_MEMBASE:
5069 case OP_LOADR8_MEMBASE:
5070 case OP_LOAD_MEMBASE:
5078 LLVMValueRef base, index, addr;
5080 gboolean sext = FALSE, zext = FALSE;
5081 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5083 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5088 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)) {
5089 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5094 if (ins->inst_offset == 0) {
5096 } else if (ins->inst_offset % size != 0) {
5097 /* Unaligned load */
5098 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5099 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5101 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5102 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5106 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5108 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5110 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5112 * These will signal LLVM that these loads do not alias any stores, and
5113 * they can't fail, allowing them to be hoisted out of loops.
5115 set_invariant_load_flag (values [ins->dreg]);
5116 #if LLVM_API_VERSION < 100
5117 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5122 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5124 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5125 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5126 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5130 case OP_STOREI1_MEMBASE_REG:
5131 case OP_STOREI2_MEMBASE_REG:
5132 case OP_STOREI4_MEMBASE_REG:
5133 case OP_STOREI8_MEMBASE_REG:
5134 case OP_STORER4_MEMBASE_REG:
5135 case OP_STORER8_MEMBASE_REG:
5136 case OP_STORE_MEMBASE_REG: {
5138 LLVMValueRef index, addr;
5140 gboolean sext = FALSE, zext = FALSE;
5141 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5143 if (!values [ins->inst_destbasereg]) {
5144 set_failure (ctx, "inst_destbasereg");
5148 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5150 if (ins->inst_offset % size != 0) {
5151 /* Unaligned store */
5152 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5153 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5155 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5156 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5158 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5162 case OP_STOREI1_MEMBASE_IMM:
5163 case OP_STOREI2_MEMBASE_IMM:
5164 case OP_STOREI4_MEMBASE_IMM:
5165 case OP_STOREI8_MEMBASE_IMM:
5166 case OP_STORE_MEMBASE_IMM: {
5168 LLVMValueRef index, addr;
5170 gboolean sext = FALSE, zext = FALSE;
5171 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5173 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5175 if (ins->inst_offset % size != 0) {
5176 /* Unaligned store */
5177 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5178 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5180 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5181 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5183 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5188 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5190 case OP_OUTARG_VTRETADDR:
5198 case OP_VOIDCALL_MEMBASE:
5199 case OP_CALL_MEMBASE:
5200 case OP_LCALL_MEMBASE:
5201 case OP_FCALL_MEMBASE:
5202 case OP_RCALL_MEMBASE:
5203 case OP_VCALL_MEMBASE:
5204 case OP_VOIDCALL_REG:
5209 case OP_VCALL_REG: {
5210 process_call (ctx, bb, &builder, ins);
5215 LLVMValueRef indexes [2];
5216 MonoJumpInfo *tmp_ji, *ji;
5217 LLVMValueRef got_entry_addr;
5221 * FIXME: Can't allocate from the cfg mempool since that is freed if
5222 * the LLVM compile fails.
5224 tmp_ji = g_new0 (MonoJumpInfo, 1);
5225 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5226 tmp_ji->data.target = ins->inst_p0;
5228 ji = mono_aot_patch_info_dup (tmp_ji);
5231 ji->next = cfg->patch_info;
5232 cfg->patch_info = ji;
5234 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5235 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5236 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5237 if (!mono_aot_is_shared_got_offset (got_offset)) {
5238 //mono_print_ji (ji);
5240 ctx->has_got_access = TRUE;
5243 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5244 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5245 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5247 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5248 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5250 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5251 if (!cfg->llvm_only)
5252 set_invariant_load_flag (values [ins->dreg]);
5255 case OP_NOT_REACHED:
5256 LLVMBuildUnreachable (builder);
5257 has_terminator = TRUE;
5258 g_assert (bb->block_num < cfg->max_block_num);
5259 ctx->unreachable [bb->block_num] = TRUE;
5260 /* Might have instructions after this */
5262 MonoInst *next = ins->next;
5264 * FIXME: If later code uses the regs defined by these instructions,
5265 * compilation will fail.
5267 MONO_DELETE_INS (bb, next);
5271 MonoInst *var = ins->inst_i0;
5273 if (var->opcode == OP_VTARG_ADDR) {
5274 /* The variable contains the vtype address */
5275 values [ins->dreg] = values [var->dreg];
5276 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5277 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5279 values [ins->dreg] = addresses [var->dreg];
5284 LLVMValueRef args [1];
5286 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5287 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5291 LLVMValueRef args [1];
5293 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5294 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5298 LLVMValueRef args [1];
5300 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5301 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5305 LLVMValueRef args [1];
5307 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5308 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5322 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5323 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5325 switch (ins->opcode) {
5328 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5332 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5336 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5340 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5343 g_assert_not_reached ();
5346 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5349 case OP_ATOMIC_EXCHANGE_I4:
5350 case OP_ATOMIC_EXCHANGE_I8: {
5351 LLVMValueRef args [2];
5354 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5355 t = LLVMInt32Type ();
5357 t = LLVMInt64Type ();
5359 g_assert (ins->inst_offset == 0);
5361 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5362 args [1] = convert (ctx, rhs, t);
5364 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5367 case OP_ATOMIC_ADD_I4:
5368 case OP_ATOMIC_ADD_I8: {
5369 LLVMValueRef args [2];
5372 if (ins->opcode == OP_ATOMIC_ADD_I4)
5373 t = LLVMInt32Type ();
5375 t = LLVMInt64Type ();
5377 g_assert (ins->inst_offset == 0);
5379 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5380 args [1] = convert (ctx, rhs, t);
5381 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5384 case OP_ATOMIC_CAS_I4:
5385 case OP_ATOMIC_CAS_I8: {
5386 LLVMValueRef args [3], val;
5389 if (ins->opcode == OP_ATOMIC_CAS_I4)
5390 t = LLVMInt32Type ();
5392 t = LLVMInt64Type ();
5394 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5396 args [1] = convert (ctx, values [ins->sreg3], t);
5398 args [2] = convert (ctx, values [ins->sreg2], t);
5399 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5400 /* cmpxchg returns a pair */
5401 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5404 case OP_MEMORY_BARRIER: {
5405 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5408 case OP_ATOMIC_LOAD_I1:
5409 case OP_ATOMIC_LOAD_I2:
5410 case OP_ATOMIC_LOAD_I4:
5411 case OP_ATOMIC_LOAD_I8:
5412 case OP_ATOMIC_LOAD_U1:
5413 case OP_ATOMIC_LOAD_U2:
5414 case OP_ATOMIC_LOAD_U4:
5415 case OP_ATOMIC_LOAD_U8:
5416 case OP_ATOMIC_LOAD_R4:
5417 case OP_ATOMIC_LOAD_R8: {
5418 set_failure (ctx, "atomic mono.load intrinsic");
5422 gboolean sext, zext;
5424 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5425 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5426 LLVMValueRef index, addr;
5428 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5433 if (ins->inst_offset != 0) {
5434 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5435 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5440 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5442 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5445 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5447 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5451 case OP_ATOMIC_STORE_I1:
5452 case OP_ATOMIC_STORE_I2:
5453 case OP_ATOMIC_STORE_I4:
5454 case OP_ATOMIC_STORE_I8:
5455 case OP_ATOMIC_STORE_U1:
5456 case OP_ATOMIC_STORE_U2:
5457 case OP_ATOMIC_STORE_U4:
5458 case OP_ATOMIC_STORE_U8:
5459 case OP_ATOMIC_STORE_R4:
5460 case OP_ATOMIC_STORE_R8: {
5461 set_failure (ctx, "atomic mono.store intrinsic");
5465 gboolean sext, zext;
5467 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5468 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5469 LLVMValueRef index, addr, value;
5471 if (!values [ins->inst_destbasereg]) {
5472 set_failure (ctx, "inst_destbasereg");
5476 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5478 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5479 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5480 value = convert (ctx, values [ins->sreg1], t);
5482 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5486 case OP_RELAXED_NOP: {
5487 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5488 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5495 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5497 // 257 == FS segment register
5498 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5500 // 256 == GS segment register
5501 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5504 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5505 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5506 /* See mono_amd64_emit_tls_get () */
5507 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5509 // 256 == GS segment register
5510 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5511 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5513 set_failure (ctx, "opcode tls-get");
5519 case OP_TLS_GET_REG: {
5520 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5521 /* See emit_tls_get_reg () */
5522 // 256 == GS segment register
5523 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5524 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5526 set_failure (ctx, "opcode tls-get");
5532 case OP_TLS_SET_REG: {
5533 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5534 /* See emit_tls_get_reg () */
5535 // 256 == GS segment register
5536 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5537 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5539 set_failure (ctx, "opcode tls-set-reg");
5549 case OP_IADD_OVF_UN:
5551 case OP_ISUB_OVF_UN:
5553 case OP_IMUL_OVF_UN:
5554 #if SIZEOF_VOID_P == 8
5556 case OP_LADD_OVF_UN:
5558 case OP_LSUB_OVF_UN:
5560 case OP_LMUL_OVF_UN:
5563 LLVMValueRef args [2], val, ovf, func;
5565 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5566 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5567 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5569 val = LLVMBuildCall (builder, func, args, 2, "");
5570 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5571 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5572 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5575 builder = ctx->builder;
5581 * We currently model them using arrays. Promotion to local vregs is
5582 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5583 * so we always have an entry in cfg->varinfo for them.
5584 * FIXME: Is this needed ?
5587 MonoClass *klass = ins->klass;
5588 LLVMValueRef args [5];
5592 set_failure (ctx, "!klass");
5596 if (!addresses [ins->dreg])
5597 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5598 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5599 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5600 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5602 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5603 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5604 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5607 case OP_DUMMY_VZERO:
5610 case OP_STOREV_MEMBASE:
5611 case OP_LOADV_MEMBASE:
5613 MonoClass *klass = ins->klass;
5614 LLVMValueRef src = NULL, dst, args [5];
5615 gboolean done = FALSE;
5619 set_failure (ctx, "!klass");
5623 if (mini_is_gsharedvt_klass (klass)) {
5625 set_failure (ctx, "gsharedvt");
5629 switch (ins->opcode) {
5630 case OP_STOREV_MEMBASE:
5631 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5632 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5633 /* Decomposed earlier */
5634 g_assert_not_reached ();
5637 if (!addresses [ins->sreg1]) {
5639 g_assert (values [ins->sreg1]);
5640 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));
5641 LLVMBuildStore (builder, values [ins->sreg1], dst);
5644 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5645 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5648 case OP_LOADV_MEMBASE:
5649 if (!addresses [ins->dreg])
5650 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5651 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5652 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5655 if (!addresses [ins->sreg1])
5656 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5657 if (!addresses [ins->dreg])
5658 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5659 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5660 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5663 g_assert_not_reached ();
5673 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5674 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5676 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5677 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5678 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5681 case OP_LLVM_OUTARG_VT: {
5682 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5683 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5685 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5686 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5688 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5689 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5691 g_assert (addresses [ins->sreg1]);
5692 addresses [ins->dreg] = addresses [ins->sreg1];
5694 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5695 if (!addresses [ins->sreg1]) {
5696 addresses [ins->sreg1] = build_alloca (ctx, t);
5697 g_assert (values [ins->sreg1]);
5699 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5700 addresses [ins->dreg] = addresses [ins->sreg1];
5702 if (!addresses [ins->sreg1]) {
5703 addresses [ins->sreg1] = build_alloca (ctx, t);
5704 g_assert (values [ins->sreg1]);
5705 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5707 addresses [ins->dreg] = addresses [ins->sreg1];
5715 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5717 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5720 case OP_LOADX_MEMBASE: {
5721 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5724 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5725 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5728 case OP_STOREX_MEMBASE: {
5729 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5732 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5733 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5740 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5744 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5750 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5754 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5758 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5762 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5765 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5768 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5771 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5775 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5786 LLVMValueRef v = NULL;
5788 switch (ins->opcode) {
5793 t = LLVMVectorType (LLVMInt32Type (), 4);
5794 rt = LLVMVectorType (LLVMFloatType (), 4);
5800 t = LLVMVectorType (LLVMInt64Type (), 2);
5801 rt = LLVMVectorType (LLVMDoubleType (), 2);
5804 t = LLVMInt32Type ();
5805 rt = LLVMInt32Type ();
5806 g_assert_not_reached ();
5809 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5810 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5811 switch (ins->opcode) {
5814 v = LLVMBuildAnd (builder, lhs, rhs, "");
5818 v = LLVMBuildOr (builder, lhs, rhs, "");
5822 v = LLVMBuildXor (builder, lhs, rhs, "");
5826 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5829 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5853 case OP_PADDB_SAT_UN:
5854 case OP_PADDW_SAT_UN:
5855 case OP_PSUBB_SAT_UN:
5856 case OP_PSUBW_SAT_UN:
5864 case OP_PMULW_HIGH_UN: {
5865 LLVMValueRef args [2];
5870 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5877 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5881 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5889 case OP_EXTRACTX_U2:
5891 case OP_EXTRACT_U1: {
5893 gboolean zext = FALSE;
5895 t = simd_op_to_llvm_type (ins->opcode);
5897 switch (ins->opcode) {
5905 case OP_EXTRACTX_U2:
5910 t = LLVMInt32Type ();
5911 g_assert_not_reached ();
5914 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5915 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5917 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5926 case OP_EXPAND_R8: {
5927 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5928 LLVMValueRef mask [16], v;
5931 for (i = 0; i < 16; ++i)
5932 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5934 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5936 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5937 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5942 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5945 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5948 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5951 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5954 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5957 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5968 case OP_EXTRACT_MASK:
5975 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5977 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5983 LLVMValueRef args [3];
5987 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5989 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5994 /* This is only used for implementing shifts by non-immediate */
5995 values [ins->dreg] = lhs;
6006 LLVMValueRef args [3];
6009 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6011 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6022 case OP_PSHLQ_REG: {
6023 LLVMValueRef args [3];
6026 args [1] = values [ins->sreg2];
6028 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6035 case OP_PSHUFLEW_LOW:
6036 case OP_PSHUFLEW_HIGH: {
6038 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6039 int i, mask_size = 0;
6040 int imask = ins->inst_c0;
6042 /* Convert the x86 shuffle mask to LLVM's */
6043 switch (ins->opcode) {
6046 mask [0] = ((imask >> 0) & 3);
6047 mask [1] = ((imask >> 2) & 3);
6048 mask [2] = ((imask >> 4) & 3) + 4;
6049 mask [3] = ((imask >> 6) & 3) + 4;
6050 v1 = values [ins->sreg1];
6051 v2 = values [ins->sreg2];
6055 mask [0] = ((imask >> 0) & 1);
6056 mask [1] = ((imask >> 1) & 1) + 2;
6057 v1 = values [ins->sreg1];
6058 v2 = values [ins->sreg2];
6060 case OP_PSHUFLEW_LOW:
6062 mask [0] = ((imask >> 0) & 3);
6063 mask [1] = ((imask >> 2) & 3);
6064 mask [2] = ((imask >> 4) & 3);
6065 mask [3] = ((imask >> 6) & 3);
6070 v1 = values [ins->sreg1];
6071 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6073 case OP_PSHUFLEW_HIGH:
6079 mask [4] = 4 + ((imask >> 0) & 3);
6080 mask [5] = 4 + ((imask >> 2) & 3);
6081 mask [6] = 4 + ((imask >> 4) & 3);
6082 mask [7] = 4 + ((imask >> 6) & 3);
6083 v1 = values [ins->sreg1];
6084 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6088 mask [0] = ((imask >> 0) & 3);
6089 mask [1] = ((imask >> 2) & 3);
6090 mask [2] = ((imask >> 4) & 3);
6091 mask [3] = ((imask >> 6) & 3);
6092 v1 = values [ins->sreg1];
6093 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6096 g_assert_not_reached ();
6098 for (i = 0; i < mask_size; ++i)
6099 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6101 values [ins->dreg] =
6102 LLVMBuildShuffleVector (builder, v1, v2,
6103 LLVMConstVector (mask_values, mask_size), dname);
6107 case OP_UNPACK_LOWB:
6108 case OP_UNPACK_LOWW:
6109 case OP_UNPACK_LOWD:
6110 case OP_UNPACK_LOWQ:
6111 case OP_UNPACK_LOWPS:
6112 case OP_UNPACK_LOWPD:
6113 case OP_UNPACK_HIGHB:
6114 case OP_UNPACK_HIGHW:
6115 case OP_UNPACK_HIGHD:
6116 case OP_UNPACK_HIGHQ:
6117 case OP_UNPACK_HIGHPS:
6118 case OP_UNPACK_HIGHPD: {
6120 LLVMValueRef mask_values [16];
6121 int i, mask_size = 0;
6122 gboolean low = FALSE;
6124 switch (ins->opcode) {
6125 case OP_UNPACK_LOWB:
6129 case OP_UNPACK_LOWW:
6133 case OP_UNPACK_LOWD:
6134 case OP_UNPACK_LOWPS:
6138 case OP_UNPACK_LOWQ:
6139 case OP_UNPACK_LOWPD:
6143 case OP_UNPACK_HIGHB:
6146 case OP_UNPACK_HIGHW:
6149 case OP_UNPACK_HIGHD:
6150 case OP_UNPACK_HIGHPS:
6153 case OP_UNPACK_HIGHQ:
6154 case OP_UNPACK_HIGHPD:
6158 g_assert_not_reached ();
6162 for (i = 0; i < (mask_size / 2); ++i) {
6164 mask [(i * 2) + 1] = mask_size + i;
6167 for (i = 0; i < (mask_size / 2); ++i) {
6168 mask [(i * 2)] = (mask_size / 2) + i;
6169 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6173 for (i = 0; i < mask_size; ++i)
6174 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6176 values [ins->dreg] =
6177 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6178 LLVMConstVector (mask_values, mask_size), dname);
6183 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6184 LLVMValueRef v, val;
6186 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6187 val = LLVMConstNull (t);
6188 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6189 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6191 values [ins->dreg] = val;
6195 case OP_DUPPS_HIGH: {
6196 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6197 LLVMValueRef v1, v2, val;
6200 if (ins->opcode == OP_DUPPS_LOW) {
6201 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6202 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6204 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6205 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6207 val = LLVMConstNull (t);
6208 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6209 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6210 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6211 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6213 values [ins->dreg] = val;
6223 * EXCEPTION HANDLING
6225 case OP_IMPLICIT_EXCEPTION:
6226 /* This marks a place where an implicit exception can happen */
6227 if (bb->region != -1)
6228 set_failure (ctx, "implicit-exception");
6232 gboolean rethrow = (ins->opcode == OP_RETHROW);
6233 if (ctx->llvm_only) {
6234 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6235 has_terminator = TRUE;
6236 ctx->unreachable [bb->block_num] = TRUE;
6238 emit_throw (ctx, bb, rethrow, lhs);
6239 builder = ctx->builder;
6243 case OP_CALL_HANDLER: {
6245 * We don't 'call' handlers, but instead simply branch to them.
6246 * The code generated by ENDFINALLY will branch back to us.
6248 LLVMBasicBlockRef noex_bb;
6250 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6252 bb_list = info->call_handler_return_bbs;
6255 * Set the indicator variable for the finally clause.
6257 lhs = info->finally_ind;
6259 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6261 /* Branch to the finally clause */
6262 LLVMBuildBr (builder, info->call_handler_target_bb);
6264 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6265 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6267 builder = ctx->builder = create_builder (ctx);
6268 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6270 bblocks [bb->block_num].end_bblock = noex_bb;
6273 case OP_START_HANDLER: {
6276 case OP_ENDFINALLY: {
6277 LLVMBasicBlockRef resume_bb;
6278 MonoBasicBlock *handler_bb;
6279 LLVMValueRef val, switch_ins, callee;
6283 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6284 g_assert (handler_bb);
6285 info = &bblocks [handler_bb->block_num];
6286 lhs = info->finally_ind;
6289 bb_list = info->call_handler_return_bbs;
6291 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6293 /* Load the finally variable */
6294 val = LLVMBuildLoad (builder, lhs, "");
6296 /* Reset the variable */
6297 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6299 /* Branch to either resume_bb, or to the bblocks in bb_list */
6300 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6302 * The other targets are added at the end to handle OP_CALL_HANDLER
6303 * opcodes processed later.
6305 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6307 builder = ctx->builder = create_builder (ctx);
6308 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6310 if (ctx->llvm_only) {
6311 emit_resume_eh (ctx, bb);
6313 if (ctx->cfg->compile_aot) {
6314 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6316 #if LLVM_API_VERSION > 100
6317 MonoJitICallInfo *info;
6319 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6321 gpointer target = (void*)info->func;
6322 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6323 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6325 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6328 LLVMBuildCall (builder, callee, NULL, 0, "");
6329 LLVMBuildUnreachable (builder);
6332 has_terminator = TRUE;
6335 case OP_IL_SEQ_POINT:
6340 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6341 set_failure (ctx, reason);
6349 /* Convert the value to the type required by phi nodes */
6350 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6351 if (!values [ins->dreg])
6353 values [ins->dreg] = addresses [ins->dreg];
6355 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6358 /* Add stores for volatile variables */
6359 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6360 emit_volatile_store (ctx, ins->dreg);
6366 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6367 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6370 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6371 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6372 LLVMBuildRetVoid (builder);
6375 if (bb == cfg->bb_entry)
6376 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6380 * mono_llvm_check_method_supported:
6382 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6383 * compiling a method twice.
6386 mono_llvm_check_method_supported (MonoCompile *cfg)
6393 if (cfg->method->save_lmf) {
6394 cfg->exception_message = g_strdup ("lmf");
6395 cfg->disable_llvm = TRUE;
6397 if (cfg->disable_llvm)
6401 * Nested clauses where one of the clauses is a finally clause is
6402 * not supported, because LLVM can't figure out the control flow,
6403 * probably because we resume exception handling by calling our
6404 * own function instead of using the 'resume' llvm instruction.
6406 for (i = 0; i < cfg->header->num_clauses; ++i) {
6407 for (j = 0; j < cfg->header->num_clauses; ++j) {
6408 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6409 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6411 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6412 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6413 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6414 cfg->exception_message = g_strdup ("nested clauses");
6415 cfg->disable_llvm = TRUE;
6420 if (cfg->disable_llvm)
6424 if (cfg->method->dynamic) {
6425 cfg->exception_message = g_strdup ("dynamic.");
6426 cfg->disable_llvm = TRUE;
6428 if (cfg->disable_llvm)
6432 static LLVMCallInfo*
6433 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6435 LLVMCallInfo *linfo;
6438 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6442 * Gsharedvt methods have the following calling convention:
6443 * - all arguments are passed by ref, even non generic ones
6444 * - the return value is returned by ref too, using a vret
6445 * argument passed after 'this'.
6447 n = sig->param_count + sig->hasthis;
6448 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6452 linfo->args [pindex ++].storage = LLVMArgNormal;
6454 if (sig->ret->type != MONO_TYPE_VOID) {
6455 if (mini_is_gsharedvt_variable_type (sig->ret))
6456 linfo->ret.storage = LLVMArgGsharedvtVariable;
6457 else if (mini_type_is_vtype (sig->ret))
6458 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6460 linfo->ret.storage = LLVMArgGsharedvtFixed;
6461 linfo->vret_arg_index = pindex;
6463 linfo->ret.storage = LLVMArgNone;
6466 for (i = 0; i < sig->param_count; ++i) {
6467 if (sig->params [i]->byref)
6468 linfo->args [pindex].storage = LLVMArgNormal;
6469 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6470 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6471 else if (mini_type_is_vtype (sig->params [i]))
6472 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6474 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6475 linfo->args [pindex].type = sig->params [i];
6482 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6483 for (i = 0; i < sig->param_count; ++i)
6484 linfo->args [i + sig->hasthis].type = sig->params [i];
6490 emit_method_inner (EmitContext *ctx);
6493 free_ctx (EmitContext *ctx)
6497 g_free (ctx->values);
6498 g_free (ctx->addresses);
6499 g_free (ctx->vreg_types);
6500 g_free (ctx->vreg_cli_types);
6501 g_free (ctx->is_dead);
6502 g_free (ctx->unreachable);
6503 g_ptr_array_free (ctx->phi_values, TRUE);
6504 g_free (ctx->bblocks);
6505 g_hash_table_destroy (ctx->region_to_handler);
6506 g_hash_table_destroy (ctx->clause_to_handler);
6507 g_hash_table_destroy (ctx->jit_callees);
6508 g_free (ctx->method_name);
6509 g_ptr_array_free (ctx->bblock_list, TRUE);
6511 for (l = ctx->builders; l; l = l->next) {
6512 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6513 LLVMDisposeBuilder (builder);
6520 * mono_llvm_emit_method:
6522 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6525 mono_llvm_emit_method (MonoCompile *cfg)
6529 gboolean is_linkonce = FALSE;
6532 /* The code below might acquire the loader lock, so use it for global locking */
6533 mono_loader_lock ();
6535 /* Used to communicate with the callbacks */
6536 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6538 ctx = g_new0 (EmitContext, 1);
6540 ctx->mempool = cfg->mempool;
6543 * This maps vregs to the LLVM instruction defining them
6545 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6547 * This maps vregs for volatile variables to the LLVM instruction defining their
6550 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6551 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6552 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6553 ctx->phi_values = g_ptr_array_sized_new (256);
6555 * This signals whenever the vreg was defined by a phi node with no input vars
6556 * (i.e. all its input bblocks end with NOT_REACHABLE).
6558 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6559 /* Whenever the bblock is unreachable */
6560 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6561 ctx->bblock_list = g_ptr_array_sized_new (256);
6563 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6564 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6565 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6566 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6567 if (cfg->compile_aot) {
6568 ctx->module = &aot_module;
6572 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6573 * linkage for them. This requires the following:
6574 * - the method needs to have a unique mangled name
6575 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6577 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6579 method_name = mono_aot_get_mangled_method_name (cfg->method);
6581 is_linkonce = FALSE;
6584 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6586 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6590 method_name = mono_aot_get_method_name (cfg);
6591 cfg->llvm_method_name = g_strdup (method_name);
6593 init_jit_module (cfg->domain);
6594 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6595 method_name = mono_method_full_name (cfg->method, TRUE);
6597 ctx->method_name = method_name;
6598 ctx->is_linkonce = is_linkonce;
6600 #if LLVM_API_VERSION > 100
6601 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6603 ctx->lmodule = ctx->module->lmodule;
6605 ctx->llvm_only = ctx->module->llvm_only;
6607 emit_method_inner (ctx);
6609 if (!ctx_ok (ctx)) {
6611 /* Need to add unused phi nodes as they can be referenced by other values */
6612 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6613 LLVMBuilderRef builder;
6615 builder = create_builder (ctx);
6616 LLVMPositionBuilderAtEnd (builder, phi_bb);
6618 for (i = 0; i < ctx->phi_values->len; ++i) {
6619 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6620 if (LLVMGetInstructionParent (v) == NULL)
6621 LLVMInsertIntoBuilder (builder, v);
6624 LLVMDeleteFunction (ctx->lmethod);
6630 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6632 mono_loader_unlock ();
6636 emit_method_inner (EmitContext *ctx)
6638 MonoCompile *cfg = ctx->cfg;
6639 MonoMethodSignature *sig;
6641 LLVMTypeRef method_type;
6642 LLVMValueRef method = NULL;
6643 LLVMValueRef *values = ctx->values;
6644 int i, max_block_num, bb_index;
6645 gboolean last = FALSE;
6646 LLVMCallInfo *linfo;
6647 LLVMModuleRef lmodule = ctx->lmodule;
6649 GPtrArray *bblock_list = ctx->bblock_list;
6650 MonoMethodHeader *header;
6651 MonoExceptionClause *clause;
6654 if (cfg->gsharedvt && !cfg->llvm_only) {
6655 set_failure (ctx, "gsharedvt");
6661 static int count = 0;
6664 if (g_getenv ("LLVM_COUNT")) {
6665 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6666 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6670 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6671 set_failure (ctx, "count");
6678 sig = mono_method_signature (cfg->method);
6681 linfo = get_llvm_call_info (cfg, sig);
6687 linfo->rgctx_arg = TRUE;
6688 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6692 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6693 ctx->lmethod = method;
6695 if (!cfg->llvm_only)
6696 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6697 LLVMSetLinkage (method, LLVMPrivateLinkage);
6699 LLVMAddFunctionAttr (method, LLVMUWTable);
6701 if (cfg->compile_aot) {
6702 LLVMSetLinkage (method, LLVMInternalLinkage);
6703 if (ctx->module->external_symbols) {
6704 LLVMSetLinkage (method, LLVMExternalLinkage);
6705 LLVMSetVisibility (method, LLVMHiddenVisibility);
6707 if (ctx->is_linkonce) {
6708 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6709 LLVMSetVisibility (method, LLVMDefaultVisibility);
6712 #if LLVM_API_VERSION > 100
6713 LLVMSetLinkage (method, LLVMExternalLinkage);
6715 LLVMSetLinkage (method, LLVMPrivateLinkage);
6719 if (cfg->method->save_lmf && !cfg->llvm_only) {
6720 set_failure (ctx, "lmf");
6724 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6725 set_failure (ctx, "pinvoke signature");
6729 header = cfg->header;
6730 for (i = 0; i < header->num_clauses; ++i) {
6731 clause = &header->clauses [i];
6732 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6733 set_failure (ctx, "non-finally/catch clause.");
6737 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6738 /* We can't handle inlined methods with clauses */
6739 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6741 if (linfo->rgctx_arg) {
6742 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6743 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6745 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6746 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6747 * CC_X86_64_Mono in X86CallingConv.td.
6749 if (!ctx->llvm_only)
6750 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6751 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6753 ctx->rgctx_arg_pindex = -1;
6755 if (cfg->vret_addr) {
6756 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6757 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6758 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6759 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6760 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6765 ctx->this_arg_pindex = linfo->this_arg_pindex;
6766 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6767 values [cfg->args [0]->dreg] = ctx->this_arg;
6768 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6771 names = g_new (char *, sig->param_count);
6772 mono_method_get_param_names (cfg->method, (const char **) names);
6774 for (i = 0; i < sig->param_count; ++i) {
6775 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6777 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6780 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6781 name = g_strdup_printf ("dummy_%d_%d", i, j);
6782 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6786 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6787 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6788 if (names [i] && names [i][0] != '\0')
6789 name = g_strdup_printf ("p_arg_%s", names [i]);
6791 name = g_strdup_printf ("p_arg_%d", i);
6793 if (names [i] && names [i][0] != '\0')
6794 name = g_strdup_printf ("arg_%s", names [i]);
6796 name = g_strdup_printf ("arg_%d", i);
6798 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6800 if (ainfo->storage == LLVMArgVtypeByVal)
6801 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6803 if (ainfo->storage == LLVMArgVtypeByRef) {
6805 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6810 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6811 ctx->minfo = mono_debug_lookup_method (cfg->method);
6812 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6816 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6817 max_block_num = MAX (max_block_num, bb->block_num);
6818 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6820 /* Add branches between non-consecutive bblocks */
6821 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6822 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6823 bb->next_bb != bb->last_ins->inst_false_bb) {
6825 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6826 inst->opcode = OP_BR;
6827 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6828 mono_bblock_add_inst (bb, inst);
6833 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6834 * was later optimized away, so clear these flags, and add them back for the still
6835 * present OP_LDADDR instructions.
6837 for (i = 0; i < cfg->next_vreg; ++i) {
6840 ins = get_vreg_to_inst (cfg, i);
6841 if (ins && ins != cfg->rgctx_var)
6842 ins->flags &= ~MONO_INST_INDIRECT;
6846 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6848 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6850 LLVMBuilderRef builder;
6852 char dname_buf[128];
6854 builder = create_builder (ctx);
6856 for (ins = bb->code; ins; ins = ins->next) {
6857 switch (ins->opcode) {
6862 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6867 if (ins->opcode == OP_VPHI) {
6868 /* Treat valuetype PHI nodes as operating on the address itself */
6869 g_assert (ins->klass);
6870 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6874 * Have to precreate these, as they can be referenced by
6875 * earlier instructions.
6877 sprintf (dname_buf, "t%d", ins->dreg);
6879 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6881 if (ins->opcode == OP_VPHI)
6882 ctx->addresses [ins->dreg] = values [ins->dreg];
6884 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6887 * Set the expected type of the incoming arguments since these have
6888 * to have the same type.
6890 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6891 int sreg1 = ins->inst_phi_args [i + 1];
6894 ctx->vreg_types [sreg1] = phi_type;
6899 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6908 * Create an ordering for bblocks, use the depth first order first, then
6909 * put the exception handling bblocks last.
6911 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6912 bb = cfg->bblocks [bb_index];
6913 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6914 g_ptr_array_add (bblock_list, bb);
6915 bblocks [bb->block_num].added = TRUE;
6919 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6920 if (!bblocks [bb->block_num].added)
6921 g_ptr_array_add (bblock_list, bb);
6925 * Second pass: generate code.
6928 LLVMBuilderRef entry_builder = create_builder (ctx);
6929 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6930 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6931 emit_entry_bb (ctx, entry_builder);
6933 // Make landing pads first
6934 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6936 if (ctx->llvm_only) {
6937 size_t group_index = 0;
6938 while (group_index < cfg->header->num_clauses) {
6940 size_t cursor = group_index;
6941 while (cursor < cfg->header->num_clauses &&
6942 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6943 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6948 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6949 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6950 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6952 group_index = cursor;
6956 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6957 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6959 // Prune unreachable mono BBs.
6960 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6963 process_bb (ctx, bb);
6967 g_hash_table_destroy (ctx->exc_meta);
6969 mono_memory_barrier ();
6971 /* Add incoming phi values */
6972 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6973 GSList *l, *ins_list;
6975 ins_list = bblocks [bb->block_num].phi_nodes;
6977 for (l = ins_list; l; l = l->next) {
6978 PhiNode *node = (PhiNode*)l->data;
6979 MonoInst *phi = node->phi;
6980 int sreg1 = node->sreg;
6981 LLVMBasicBlockRef in_bb;
6986 in_bb = get_end_bb (ctx, node->in_bb);
6988 if (ctx->unreachable [node->in_bb->block_num])
6991 if (!values [sreg1]) {
6992 /* Can happen with values in EH clauses */
6993 set_failure (ctx, "incoming phi sreg1");
6997 if (phi->opcode == OP_VPHI) {
6998 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6999 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7001 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7002 set_failure (ctx, "incoming phi arg type mismatch");
7005 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7006 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7011 /* Nullify empty phi instructions */
7012 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7013 GSList *l, *ins_list;
7015 ins_list = bblocks [bb->block_num].phi_nodes;
7017 for (l = ins_list; l; l = l->next) {
7018 PhiNode *node = (PhiNode*)l->data;
7019 MonoInst *phi = node->phi;
7020 LLVMValueRef phi_ins = values [phi->dreg];
7023 /* Already removed */
7026 if (LLVMCountIncoming (phi_ins) == 0) {
7027 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7028 LLVMInstructionEraseFromParent (phi_ins);
7029 values [phi->dreg] = NULL;
7034 /* Create the SWITCH statements for ENDFINALLY instructions */
7035 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7036 BBInfo *info = &bblocks [bb->block_num];
7038 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7039 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7040 GSList *bb_list = info->call_handler_return_bbs;
7042 for (i = 0; i < g_slist_length (bb_list); ++i)
7043 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7047 /* Initialize the method if needed */
7048 if (cfg->compile_aot && ctx->llvm_only) {
7049 // FIXME: Add more shared got entries
7050 ctx->builder = create_builder (ctx);
7051 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7053 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7055 // FIXME: beforefieldinit
7056 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7057 emit_init_method (ctx);
7059 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7063 if (cfg->llvm_only) {
7064 GHashTableIter iter;
7066 GSList *callers, *l, *l2;
7069 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7070 * We can't do this earlier, as it contains llvm instructions which can be
7071 * freed if compilation fails.
7072 * FIXME: Get rid of this when all methods can be llvm compiled.
7074 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7075 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7076 for (l = callers; l; l = l->next) {
7077 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7078 l2 = g_slist_prepend (l2, l->data);
7079 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7084 if (cfg->verbose_level > 1)
7085 mono_llvm_dump_value (method);
7087 if (cfg->compile_aot && !cfg->llvm_only)
7088 mark_as_used (ctx->module, method);
7090 if (cfg->compile_aot && !cfg->llvm_only) {
7091 LLVMValueRef md_args [16];
7092 LLVMValueRef md_node;
7095 method_index = mono_aot_get_method_index (cfg->orig_method);
7096 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7097 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7098 md_node = LLVMMDNode (md_args, 2);
7099 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7100 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7103 if (cfg->compile_aot) {
7104 /* Don't generate native code, keep the LLVM IR */
7105 if (cfg->verbose_level)
7106 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7108 #if LLVM_API_VERSION < 100
7109 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7110 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7111 g_assert (err == 0);
7114 //LLVMVerifyFunction(method, 0);
7115 #if LLVM_API_VERSION > 100
7116 MonoDomain *domain = mono_domain_get ();
7117 MonoJitDomainInfo *domain_info;
7118 int nvars = g_hash_table_size (ctx->jit_callees);
7119 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7120 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7121 GHashTableIter iter;
7127 * Compute the addresses of the LLVM globals pointing to the
7128 * methods called by the current method. Pass it to the trampoline
7129 * code so it can update them after their corresponding method was
7132 g_hash_table_iter_init (&iter, ctx->jit_callees);
7134 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7135 callee_vars [i ++] = var;
7137 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7139 decode_llvm_eh_info (ctx, eh_frame);
7141 mono_domain_lock (domain);
7142 domain_info = domain_jit_info (domain);
7143 if (!domain_info->llvm_jit_callees)
7144 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7145 g_hash_table_iter_init (&iter, ctx->jit_callees);
7147 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7148 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7149 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7150 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7153 mono_domain_unlock (domain);
7155 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7157 if (cfg->verbose_level > 1)
7158 mono_llvm_dump_value (ctx->lmethod);
7160 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7162 /* Set by emit_cb */
7163 g_assert (cfg->code_len);
7167 if (ctx->module->method_to_lmethod)
7168 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7169 if (ctx->module->idx_to_lmethod)
7170 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7172 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7173 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7177 * mono_llvm_create_vars:
7179 * Same as mono_arch_create_vars () for LLVM.
7182 mono_llvm_create_vars (MonoCompile *cfg)
7184 MonoMethodSignature *sig;
7186 sig = mono_method_signature (cfg->method);
7187 if (cfg->gsharedvt && cfg->llvm_only) {
7188 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7189 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7190 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7191 printf ("vret_addr = ");
7192 mono_print_ins (cfg->vret_addr);
7196 mono_arch_create_vars (cfg);
7201 * mono_llvm_emit_call:
7203 * Same as mono_arch_emit_call () for LLVM.
7206 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7209 MonoMethodSignature *sig;
7210 int i, n, stack_size;
7215 sig = call->signature;
7216 n = sig->param_count + sig->hasthis;
7218 call->cinfo = get_llvm_call_info (cfg, sig);
7220 if (cfg->disable_llvm)
7223 if (sig->call_convention == MONO_CALL_VARARG) {
7224 cfg->exception_message = g_strdup ("varargs");
7225 cfg->disable_llvm = TRUE;
7228 for (i = 0; i < n; ++i) {
7231 ainfo = call->cinfo->args + i;
7233 in = call->args [i];
7235 /* Simply remember the arguments */
7236 switch (ainfo->storage) {
7237 case LLVMArgNormal: {
7238 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7241 opcode = mono_type_to_regmove (cfg, t);
7242 if (opcode == OP_FMOVE) {
7243 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7244 ins->dreg = mono_alloc_freg (cfg);
7245 } else if (opcode == OP_LMOVE) {
7246 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7247 ins->dreg = mono_alloc_lreg (cfg);
7248 } else if (opcode == OP_RMOVE) {
7249 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7250 ins->dreg = mono_alloc_freg (cfg);
7252 MONO_INST_NEW (cfg, ins, OP_MOVE);
7253 ins->dreg = mono_alloc_ireg (cfg);
7255 ins->sreg1 = in->dreg;
7258 case LLVMArgVtypeByVal:
7259 case LLVMArgVtypeByRef:
7260 case LLVMArgVtypeInReg:
7261 case LLVMArgVtypeAsScalar:
7262 case LLVMArgAsIArgs:
7263 case LLVMArgAsFpArgs:
7264 case LLVMArgGsharedvtVariable:
7265 case LLVMArgGsharedvtFixed:
7266 case LLVMArgGsharedvtFixedVtype:
7267 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7268 ins->dreg = mono_alloc_ireg (cfg);
7269 ins->sreg1 = in->dreg;
7270 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7271 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7272 ins->inst_vtype = ainfo->type;
7273 ins->klass = mono_class_from_mono_type (ainfo->type);
7276 cfg->exception_message = g_strdup ("ainfo->storage");
7277 cfg->disable_llvm = TRUE;
7281 if (!cfg->disable_llvm) {
7282 MONO_ADD_INS (cfg->cbb, ins);
7283 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7288 static unsigned char*
7289 alloc_cb (LLVMValueRef function, int size)
7293 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7297 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7299 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7304 emitted_cb (LLVMValueRef function, void *start, void *end)
7308 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7310 cfg->code_len = (guint8*)end - (guint8*)start;
7314 exception_cb (void *data)
7317 MonoJitExceptionInfo *ei;
7318 guint32 ei_len, i, j, nested_len, nindex;
7319 gpointer *type_info;
7320 int this_reg, this_offset;
7322 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7326 * data points to a DWARF FDE structure, convert it to our unwind format and
7328 * An alternative would be to save it directly, and modify our unwinder to work
7331 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);
7332 if (cfg->verbose_level > 1)
7333 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7335 /* Count nested clauses */
7337 for (i = 0; i < ei_len; ++i) {
7338 gint32 cindex1 = *(gint32*)type_info [i];
7339 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7341 for (j = 0; j < cfg->header->num_clauses; ++j) {
7343 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7345 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7351 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7352 cfg->llvm_ex_info_len = ei_len + nested_len;
7353 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7354 /* Fill the rest of the information from the type info */
7355 for (i = 0; i < ei_len; ++i) {
7356 gint32 clause_index = *(gint32*)type_info [i];
7357 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7359 cfg->llvm_ex_info [i].flags = clause->flags;
7360 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7361 cfg->llvm_ex_info [i].clause_index = clause_index;
7365 * For nested clauses, the LLVM produced exception info associates the try interval with
7366 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7367 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7368 * and everything else from the nested clause.
7371 for (i = 0; i < ei_len; ++i) {
7372 gint32 cindex1 = *(gint32*)type_info [i];
7373 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7375 for (j = 0; j < cfg->header->num_clauses; ++j) {
7377 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7378 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7380 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7381 /* clause1 is the nested clause */
7382 nested_ei = &cfg->llvm_ex_info [i];
7383 nesting_ei = &cfg->llvm_ex_info [nindex];
7386 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7388 nesting_ei->flags = clause2->flags;
7389 nesting_ei->data.catch_class = clause2->data.catch_class;
7390 nesting_ei->clause_index = cindex2;
7394 g_assert (nindex == ei_len + nested_len);
7395 cfg->llvm_this_reg = this_reg;
7396 cfg->llvm_this_offset = this_offset;
7398 /* type_info [i] is cfg mempool allocated, no need to free it */
7404 #if LLVM_API_VERSION > 100
7406 * decode_llvm_eh_info:
7408 * Decode the EH table emitted by llvm in jit mode, and store
7409 * the result into cfg.
7412 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7414 MonoCompile *cfg = ctx->cfg;
7417 MonoLLVMFDEInfo info;
7418 MonoJitExceptionInfo *ei;
7419 guint8 *p = eh_frame;
7420 int version, fde_count, fde_offset;
7421 guint32 ei_len, i, nested_len;
7422 gpointer *type_info;
7426 * Decode the one element EH table emitted by the MonoException class
7430 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7433 g_assert (version == 3);
7436 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7438 fde_count = *(guint32*)p;
7442 g_assert (fde_count == 1);
7444 /* The only table entry */
7445 fde_offset = table [1];
7448 cfg->code_len = table [0];
7449 fde_len = table [1] - fde_offset;
7452 fde = (guint8*)eh_frame + fde_offset;
7453 cie = (guint8*)table;
7455 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7457 cfg->encoded_unwind_ops = info.unw_info;
7458 cfg->encoded_unwind_ops_len = info.unw_info_len;
7459 if (cfg->verbose_level > 1)
7460 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7461 if (info.this_reg != -1) {
7462 cfg->llvm_this_reg = info.this_reg;
7463 cfg->llvm_this_offset = info.this_offset;
7467 ei_len = info.ex_info_len;
7468 type_info = info.type_info;
7470 // Nested clauses are currently disabled
7473 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7474 cfg->llvm_ex_info_len = ei_len + nested_len;
7475 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7476 /* Fill the rest of the information from the type info */
7477 for (i = 0; i < ei_len; ++i) {
7478 gint32 clause_index = *(gint32*)type_info [i];
7479 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7481 cfg->llvm_ex_info [i].flags = clause->flags;
7482 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7483 cfg->llvm_ex_info [i].clause_index = clause_index;
7489 dlsym_cb (const char *name, void **symbol)
7495 if (!strcmp (name, "__bzero")) {
7496 *symbol = (void*)bzero;
7498 current = mono_dl_open (NULL, 0, NULL);
7501 err = mono_dl_symbol (current, name, symbol);
7503 mono_dl_close (current);
7505 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7506 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7512 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7514 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7518 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7520 LLVMTypeRef param_types [4];
7522 param_types [0] = param_type1;
7523 param_types [1] = param_type2;
7525 AddFunc (module, name, ret_type, param_types, 2);
7531 INTRINS_SADD_OVF_I32,
7532 INTRINS_UADD_OVF_I32,
7533 INTRINS_SSUB_OVF_I32,
7534 INTRINS_USUB_OVF_I32,
7535 INTRINS_SMUL_OVF_I32,
7536 INTRINS_UMUL_OVF_I32,
7537 INTRINS_SADD_OVF_I64,
7538 INTRINS_UADD_OVF_I64,
7539 INTRINS_SSUB_OVF_I64,
7540 INTRINS_USUB_OVF_I64,
7541 INTRINS_SMUL_OVF_I64,
7542 INTRINS_UMUL_OVF_I64,
7549 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7550 INTRINS_SSE_PMOVMSKB,
7551 INTRINS_SSE_PSRLI_W,
7552 INTRINS_SSE_PSRAI_W,
7553 INTRINS_SSE_PSLLI_W,
7554 INTRINS_SSE_PSRLI_D,
7555 INTRINS_SSE_PSRAI_D,
7556 INTRINS_SSE_PSLLI_D,
7557 INTRINS_SSE_PSRLI_Q,
7558 INTRINS_SSE_PSLLI_Q,
7559 INTRINS_SSE_SQRT_PD,
7560 INTRINS_SSE_SQRT_PS,
7561 INTRINS_SSE_RSQRT_PS,
7563 INTRINS_SSE_CVTTPD2DQ,
7564 INTRINS_SSE_CVTTPS2DQ,
7565 INTRINS_SSE_CVTDQ2PD,
7566 INTRINS_SSE_CVTDQ2PS,
7567 INTRINS_SSE_CVTPD2DQ,
7568 INTRINS_SSE_CVTPS2DQ,
7569 INTRINS_SSE_CVTPD2PS,
7570 INTRINS_SSE_CVTPS2PD,
7573 INTRINS_SSE_PACKSSWB,
7574 INTRINS_SSE_PACKUSWB,
7575 INTRINS_SSE_PACKSSDW,
7576 INTRINS_SSE_PACKUSDW,
7581 INTRINS_SSE_ADDSUBPS,
7586 INTRINS_SSE_ADDSUBPD,
7594 INTRINS_SSE_PADDUSW,
7595 INTRINS_SSE_PSUBUSW,
7603 INTRINS_SSE_PADDUSB,
7604 INTRINS_SSE_PSUBUSB,
7616 static IntrinsicDesc intrinsics[] = {
7617 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7618 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7619 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7620 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7621 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7622 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7623 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7624 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7625 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7626 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7627 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7628 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7629 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7630 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7631 {INTRINS_SIN, "llvm.sin.f64"},
7632 {INTRINS_COS, "llvm.cos.f64"},
7633 {INTRINS_SQRT, "llvm.sqrt.f64"},
7634 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7635 {INTRINS_FABS, "fabs"},
7636 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7637 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7638 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7639 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7640 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7641 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7642 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7643 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7644 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7645 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7646 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7647 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7648 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7649 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7650 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7651 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7652 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7653 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7654 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7655 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7656 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7657 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7658 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7659 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7660 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7661 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7662 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7663 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7664 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7665 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7666 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7667 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7668 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7669 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7670 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7671 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7672 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7673 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7674 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7675 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7676 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7677 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7678 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7679 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7680 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7681 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7682 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7683 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7684 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7685 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7686 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7687 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7688 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7689 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7690 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7691 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7692 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7693 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7694 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7695 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7700 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7702 LLVMTypeRef ret_type = type_to_simd_type (type);
7703 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7707 add_intrinsic (LLVMModuleRef module, int id)
7710 LLVMTypeRef ret_type, arg_types [16];
7712 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7716 case INTRINS_MEMSET: {
7717 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7719 AddFunc (module, name, LLVMVoidType (), params, 5);
7722 case INTRINS_MEMCPY: {
7723 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7725 AddFunc (module, name, LLVMVoidType (), params, 5);
7728 case INTRINS_SADD_OVF_I32:
7729 case INTRINS_UADD_OVF_I32:
7730 case INTRINS_SSUB_OVF_I32:
7731 case INTRINS_USUB_OVF_I32:
7732 case INTRINS_SMUL_OVF_I32:
7733 case INTRINS_UMUL_OVF_I32: {
7734 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7735 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7736 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7738 AddFunc (module, name, ret_type, params, 2);
7741 case INTRINS_SADD_OVF_I64:
7742 case INTRINS_UADD_OVF_I64:
7743 case INTRINS_SSUB_OVF_I64:
7744 case INTRINS_USUB_OVF_I64:
7745 case INTRINS_SMUL_OVF_I64:
7746 case INTRINS_UMUL_OVF_I64: {
7747 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7748 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7749 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7751 AddFunc (module, name, ret_type, params, 2);
7757 case INTRINS_FABS: {
7758 LLVMTypeRef params [] = { LLVMDoubleType () };
7760 AddFunc (module, name, LLVMDoubleType (), params, 1);
7763 case INTRINS_EXPECT_I8:
7764 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7766 case INTRINS_EXPECT_I1:
7767 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7769 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7770 case INTRINS_SSE_PMOVMSKB:
7772 ret_type = LLVMInt32Type ();
7773 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7774 AddFunc (module, name, ret_type, arg_types, 1);
7776 case INTRINS_SSE_PSRLI_W:
7777 case INTRINS_SSE_PSRAI_W:
7778 case INTRINS_SSE_PSLLI_W:
7780 ret_type = type_to_simd_type (MONO_TYPE_I2);
7781 arg_types [0] = ret_type;
7782 arg_types [1] = LLVMInt32Type ();
7783 AddFunc (module, name, ret_type, arg_types, 2);
7785 case INTRINS_SSE_PSRLI_D:
7786 case INTRINS_SSE_PSRAI_D:
7787 case INTRINS_SSE_PSLLI_D:
7788 ret_type = type_to_simd_type (MONO_TYPE_I4);
7789 arg_types [0] = ret_type;
7790 arg_types [1] = LLVMInt32Type ();
7791 AddFunc (module, name, ret_type, arg_types, 2);
7793 case INTRINS_SSE_PSRLI_Q:
7794 case INTRINS_SSE_PSLLI_Q:
7795 ret_type = type_to_simd_type (MONO_TYPE_I8);
7796 arg_types [0] = ret_type;
7797 arg_types [1] = LLVMInt32Type ();
7798 AddFunc (module, name, ret_type, arg_types, 2);
7800 case INTRINS_SSE_SQRT_PD:
7802 ret_type = type_to_simd_type (MONO_TYPE_R8);
7803 arg_types [0] = ret_type;
7804 AddFunc (module, name, ret_type, arg_types, 1);
7806 case INTRINS_SSE_SQRT_PS:
7807 ret_type = type_to_simd_type (MONO_TYPE_R4);
7808 arg_types [0] = ret_type;
7809 AddFunc (module, name, ret_type, arg_types, 1);
7811 case INTRINS_SSE_RSQRT_PS:
7812 ret_type = type_to_simd_type (MONO_TYPE_R4);
7813 arg_types [0] = ret_type;
7814 AddFunc (module, name, ret_type, arg_types, 1);
7816 case INTRINS_SSE_RCP_PS:
7817 ret_type = type_to_simd_type (MONO_TYPE_R4);
7818 arg_types [0] = ret_type;
7819 AddFunc (module, name, ret_type, arg_types, 1);
7821 case INTRINS_SSE_CVTTPD2DQ:
7822 ret_type = type_to_simd_type (MONO_TYPE_I4);
7823 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7824 AddFunc (module, name, ret_type, arg_types, 1);
7826 case INTRINS_SSE_CVTTPS2DQ:
7827 ret_type = type_to_simd_type (MONO_TYPE_I4);
7828 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7829 AddFunc (module, name, ret_type, arg_types, 1);
7831 case INTRINS_SSE_CVTDQ2PD:
7832 /* Conversion ops */
7833 ret_type = type_to_simd_type (MONO_TYPE_R8);
7834 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7835 AddFunc (module, name, ret_type, arg_types, 1);
7837 case INTRINS_SSE_CVTDQ2PS:
7838 ret_type = type_to_simd_type (MONO_TYPE_R4);
7839 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7840 AddFunc (module, name, ret_type, arg_types, 1);
7842 case INTRINS_SSE_CVTPD2DQ:
7843 ret_type = type_to_simd_type (MONO_TYPE_I4);
7844 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7845 AddFunc (module, name, ret_type, arg_types, 1);
7847 case INTRINS_SSE_CVTPS2DQ:
7848 ret_type = type_to_simd_type (MONO_TYPE_I4);
7849 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7850 AddFunc (module, name, ret_type, arg_types, 1);
7852 case INTRINS_SSE_CVTPD2PS:
7853 ret_type = type_to_simd_type (MONO_TYPE_R4);
7854 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7855 AddFunc (module, name, ret_type, arg_types, 1);
7857 case INTRINS_SSE_CVTPS2PD:
7858 ret_type = type_to_simd_type (MONO_TYPE_R8);
7859 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7860 AddFunc (module, name, ret_type, arg_types, 1);
7862 case INTRINS_SSE_CMPPD:
7864 ret_type = type_to_simd_type (MONO_TYPE_R8);
7865 arg_types [0] = ret_type;
7866 arg_types [1] = ret_type;
7867 arg_types [2] = LLVMInt8Type ();
7868 AddFunc (module, name, ret_type, arg_types, 3);
7870 case INTRINS_SSE_CMPPS:
7871 ret_type = type_to_simd_type (MONO_TYPE_R4);
7872 arg_types [0] = ret_type;
7873 arg_types [1] = ret_type;
7874 arg_types [2] = LLVMInt8Type ();
7875 AddFunc (module, name, ret_type, arg_types, 3);
7877 case INTRINS_SSE_PACKSSWB:
7878 case INTRINS_SSE_PACKUSWB:
7879 case INTRINS_SSE_PACKSSDW:
7881 ret_type = type_to_simd_type (MONO_TYPE_I1);
7882 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7883 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7884 AddFunc (module, name, ret_type, arg_types, 2);
7886 case INTRINS_SSE_PACKUSDW:
7887 ret_type = type_to_simd_type (MONO_TYPE_I2);
7888 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7889 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7890 AddFunc (module, name, ret_type, arg_types, 2);
7892 /* SSE Binary ops */
7893 case INTRINS_SSE_PMINUD:
7894 case INTRINS_SSE_PMAXUD:
7895 add_sse_binary (module, name, MONO_TYPE_I4);
7897 case INTRINS_SSE_PMINUW:
7898 case INTRINS_SSE_PMINSW:
7899 case INTRINS_SSE_PMAXUW:
7900 case INTRINS_SSE_PADDSW:
7901 case INTRINS_SSE_PSUBSW:
7902 case INTRINS_SSE_PADDUSW:
7903 case INTRINS_SSE_PSUBUSW:
7904 case INTRINS_SSE_PAVGW:
7905 case INTRINS_SSE_PMULHW:
7906 case INTRINS_SSE_PMULHU:
7907 add_sse_binary (module, name, MONO_TYPE_I2);
7909 case INTRINS_SSE_MINPS:
7910 case INTRINS_SSE_MAXPS:
7911 case INTRINS_SSE_HADDPS:
7912 case INTRINS_SSE_HSUBPS:
7913 case INTRINS_SSE_ADDSUBPS:
7914 add_sse_binary (module, name, MONO_TYPE_R4);
7916 case INTRINS_SSE_MINPD:
7917 case INTRINS_SSE_MAXPD:
7918 case INTRINS_SSE_HADDPD:
7919 case INTRINS_SSE_HSUBPD:
7920 case INTRINS_SSE_ADDSUBPD:
7921 add_sse_binary (module, name, MONO_TYPE_R8);
7923 case INTRINS_SSE_PMINUB:
7924 case INTRINS_SSE_PMAXUB:
7925 case INTRINS_SE_PADDSB:
7926 case INTRINS_SSE_PSUBSB:
7927 case INTRINS_SSE_PADDUSB:
7928 case INTRINS_SSE_PSUBUSB:
7929 case INTRINS_SSE_PAVGB:
7930 add_sse_binary (module, name, MONO_TYPE_I1);
7932 case INTRINS_SSE_PAUSE:
7933 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7937 g_assert_not_reached ();
7943 get_intrinsic (EmitContext *ctx, const char *name)
7945 #if LLVM_API_VERSION > 100
7949 * Every method is emitted into its own module so
7950 * we can add intrinsics on demand.
7952 res = LLVMGetNamedFunction (ctx->lmodule, name);
7956 /* No locking needed */
7957 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7960 printf ("%s\n", name);
7961 g_assert (id != -1);
7962 add_intrinsic (ctx->lmodule, id);
7963 res = LLVMGetNamedFunction (ctx->lmodule, name);
7971 res = LLVMGetNamedFunction (ctx->lmodule, name);
7978 add_intrinsics (LLVMModuleRef module)
7982 /* Emit declarations of instrinsics */
7984 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7985 * type doesn't seem to do any locking.
7987 for (i = 0; i < INTRINS_NUM; ++i)
7988 add_intrinsic (module, i);
7992 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7994 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7997 /* SSE intrinsics */
7998 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8002 /* Load/Store intrinsics */
8004 LLVMTypeRef arg_types [5];
8008 for (i = 1; i <= 8; i *= 2) {
8009 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8010 arg_types [1] = LLVMInt32Type ();
8011 arg_types [2] = LLVMInt1Type ();
8012 arg_types [3] = LLVMInt32Type ();
8013 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8014 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8016 arg_types [0] = LLVMIntType (i * 8);
8017 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8018 arg_types [2] = LLVMInt32Type ();
8019 arg_types [3] = LLVMInt1Type ();
8020 arg_types [4] = LLVMInt32Type ();
8021 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8022 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8028 add_types (MonoLLVMModule *module)
8030 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8034 mono_llvm_init (void)
8039 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8041 h = g_hash_table_new (NULL, NULL);
8042 for (i = 0; i < INTRINS_NUM; ++i)
8043 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8044 intrins_id_to_name = h;
8046 h = g_hash_table_new (g_str_hash, g_str_equal);
8047 for (i = 0; i < INTRINS_NUM; ++i)
8048 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8049 intrins_name_to_id = h;
8053 init_jit_module (MonoDomain *domain)
8055 MonoJitDomainInfo *dinfo;
8056 MonoLLVMModule *module;
8059 dinfo = domain_jit_info (domain);
8060 if (dinfo->llvm_module)
8063 mono_loader_lock ();
8065 if (dinfo->llvm_module) {
8066 mono_loader_unlock ();
8070 module = g_new0 (MonoLLVMModule, 1);
8072 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8073 module->lmodule = LLVMModuleCreateWithName (name);
8074 module->context = LLVMGetGlobalContext ();
8076 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8078 add_intrinsics (module->lmodule);
8081 module->llvm_types = g_hash_table_new (NULL, NULL);
8083 #if LLVM_API_VERSION < 100
8084 MonoJitICallInfo *info;
8086 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8088 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8091 mono_memory_barrier ();
8093 dinfo->llvm_module = module;
8095 mono_loader_unlock ();
8099 mono_llvm_cleanup (void)
8101 MonoLLVMModule *module = &aot_module;
8103 if (module->lmodule)
8104 LLVMDisposeModule (module->lmodule);
8106 if (module->context)
8107 LLVMContextDispose (module->context);
8111 mono_llvm_free_domain_info (MonoDomain *domain)
8113 MonoJitDomainInfo *info = domain_jit_info (domain);
8114 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8120 if (module->llvm_types)
8121 g_hash_table_destroy (module->llvm_types);
8123 mono_llvm_dispose_ee (module->mono_ee);
8125 if (module->bb_names) {
8126 for (i = 0; i < module->bb_names_len; ++i)
8127 g_free (module->bb_names [i]);
8128 g_free (module->bb_names);
8130 //LLVMDisposeModule (module->module);
8134 info->llvm_module = NULL;
8138 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8140 MonoLLVMModule *module = &aot_module;
8142 /* Delete previous module */
8143 if (module->plt_entries)
8144 g_hash_table_destroy (module->plt_entries);
8145 if (module->lmodule)
8146 LLVMDisposeModule (module->lmodule);
8148 memset (module, 0, sizeof (aot_module));
8150 module->lmodule = LLVMModuleCreateWithName ("aot");
8151 module->assembly = assembly;
8152 module->global_prefix = g_strdup (global_prefix);
8153 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8154 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8155 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8156 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8157 module->external_symbols = TRUE;
8158 module->emit_dwarf = emit_dwarf;
8159 module->static_link = static_link;
8160 module->llvm_only = llvm_only;
8161 /* The first few entries are reserved */
8162 module->max_got_offset = 16;
8163 module->context = LLVMContextCreate ();
8166 /* clang ignores our debug info because it has an invalid version */
8167 module->emit_dwarf = FALSE;
8169 #if LLVM_API_VERSION > 100
8170 module->emit_dwarf = FALSE;
8173 add_intrinsics (module->lmodule);
8176 #if LLVM_API_VERSION > 100
8177 if (module->emit_dwarf) {
8178 char *dir, *build_info, *s, *cu_name;
8180 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8183 dir = g_strdup (".");
8184 build_info = mono_get_runtime_build_info ();
8185 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8186 cu_name = g_path_get_basename (assembly->image->name);
8187 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8189 g_free (build_info);
8196 * We couldn't compute the type of the LLVM global representing the got because
8197 * its size is only known after all the methods have been emitted. So create
8198 * a dummy variable, and replace all uses it with the real got variable when
8199 * its size is known in mono_llvm_emit_aot_module ().
8202 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8204 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8205 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8208 /* Add initialization array */
8210 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8212 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8213 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8217 emit_init_icall_wrappers (module);
8219 emit_llvm_code_start (module);
8221 /* Add a dummy personality function */
8222 if (!use_debug_personality) {
8223 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8224 LLVMSetLinkage (personality, LLVMExternalLinkage);
8225 mark_as_used (module, personality);
8228 /* Add a reference to the c++ exception we throw/catch */
8230 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8231 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8232 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8233 mono_llvm_set_is_constant (module->sentinel_exception);
8236 module->llvm_types = g_hash_table_new (NULL, NULL);
8237 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8238 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8239 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8240 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8241 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8242 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8243 module->method_to_callers = g_hash_table_new (NULL, NULL);
8247 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8250 LLVMValueRef res, *vals;
8252 vals = g_new0 (LLVMValueRef, nvalues);
8253 for (i = 0; i < nvalues; ++i)
8254 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8255 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8261 * mono_llvm_emit_aot_file_info:
8263 * Emit the MonoAotFileInfo structure.
8264 * Same as emit_aot_file_info () in aot-compiler.c.
8267 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8269 MonoLLVMModule *module = &aot_module;
8271 /* Save these for later */
8272 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8273 module->has_jitted_code = has_jitted_code;
8277 * mono_llvm_emit_aot_data:
8279 * Emit the binary data DATA pointed to by symbol SYMBOL.
8282 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8284 MonoLLVMModule *module = &aot_module;
8288 type = LLVMArrayType (LLVMInt8Type (), data_len);
8289 d = LLVMAddGlobal (module->lmodule, type, symbol);
8290 LLVMSetVisibility (d, LLVMHiddenVisibility);
8291 LLVMSetLinkage (d, LLVMInternalLinkage);
8292 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8293 mono_llvm_set_is_constant (d);
8296 /* Add a reference to a global defined in JITted code */
8298 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8303 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8304 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8310 emit_aot_file_info (MonoLLVMModule *module)
8312 LLVMTypeRef file_info_type;
8313 LLVMTypeRef *eltypes, eltype;
8314 LLVMValueRef info_var;
8315 LLVMValueRef *fields;
8316 int i, nfields, tindex;
8317 MonoAotFileInfo *info;
8318 LLVMModuleRef lmodule = module->lmodule;
8320 info = &module->aot_info;
8322 /* Create an LLVM type to represent MonoAotFileInfo */
8323 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8324 eltypes = g_new (LLVMTypeRef, nfields);
8326 eltypes [tindex ++] = LLVMInt32Type ();
8327 eltypes [tindex ++] = LLVMInt32Type ();
8329 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8330 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8332 for (i = 0; i < 15; ++i)
8333 eltypes [tindex ++] = LLVMInt32Type ();
8335 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8336 for (i = 0; i < 4; ++i)
8337 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8338 g_assert (tindex == nfields);
8339 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8340 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8342 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8343 if (module->static_link) {
8344 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8345 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8347 fields = g_new (LLVMValueRef, nfields);
8349 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8350 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8354 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8355 * for symbols defined in the .s file emitted by the aot compiler.
8357 eltype = eltypes [tindex];
8358 if (module->llvm_only)
8359 fields [tindex ++] = LLVMConstNull (eltype);
8361 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8362 fields [tindex ++] = module->got_var;
8363 /* llc defines this directly */
8364 if (!module->llvm_only) {
8365 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8366 fields [tindex ++] = LLVMConstNull (eltype);
8367 fields [tindex ++] = LLVMConstNull (eltype);
8369 fields [tindex ++] = LLVMConstNull (eltype);
8370 fields [tindex ++] = module->get_method;
8371 fields [tindex ++] = module->get_unbox_tramp;
8373 if (module->has_jitted_code) {
8374 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8375 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8377 fields [tindex ++] = LLVMConstNull (eltype);
8378 fields [tindex ++] = LLVMConstNull (eltype);
8380 if (!module->llvm_only)
8381 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8383 fields [tindex ++] = LLVMConstNull (eltype);
8384 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8385 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8386 fields [tindex ++] = LLVMConstNull (eltype);
8388 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8389 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8390 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8391 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8392 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8393 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8394 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8395 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8397 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8399 /* Not needed (mem_end) */
8400 fields [tindex ++] = LLVMConstNull (eltype);
8401 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8402 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8403 if (info->trampoline_size [0]) {
8404 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8405 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8406 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8407 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8409 fields [tindex ++] = LLVMConstNull (eltype);
8410 fields [tindex ++] = LLVMConstNull (eltype);
8411 fields [tindex ++] = LLVMConstNull (eltype);
8412 fields [tindex ++] = LLVMConstNull (eltype);
8414 if (module->static_link && !module->llvm_only)
8415 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8417 fields [tindex ++] = LLVMConstNull (eltype);
8418 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8419 if (!module->llvm_only) {
8420 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8421 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8422 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8423 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8424 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8425 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8427 fields [tindex ++] = LLVMConstNull (eltype);
8428 fields [tindex ++] = LLVMConstNull (eltype);
8429 fields [tindex ++] = LLVMConstNull (eltype);
8430 fields [tindex ++] = LLVMConstNull (eltype);
8431 fields [tindex ++] = LLVMConstNull (eltype);
8432 fields [tindex ++] = LLVMConstNull (eltype);
8435 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8436 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8439 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8440 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8441 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8442 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8449 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8450 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8451 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8452 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8453 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8455 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8456 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8457 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8458 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8459 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8460 g_assert (tindex == nfields);
8462 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8464 if (module->static_link) {
8468 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8469 /* Get rid of characters which cannot occur in symbols */
8471 for (p = s; *p; ++p) {
8472 if (!(isalnum (*p) || *p == '_'))
8475 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8477 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8478 LLVMSetLinkage (var, LLVMExternalLinkage);
8483 * Emit the aot module into the LLVM bitcode file FILENAME.
8486 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8488 LLVMTypeRef got_type, inited_type;
8489 LLVMValueRef real_got, real_inited;
8490 MonoLLVMModule *module = &aot_module;
8492 emit_llvm_code_end (module);
8495 * Create the real got variable and replace all uses of the dummy variable with
8498 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8499 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8500 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8501 if (module->external_symbols) {
8502 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8503 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8505 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8507 mono_llvm_replace_uses_of (module->got_var, real_got);
8509 mark_as_used (&aot_module, real_got);
8511 /* Delete the dummy got so it doesn't become a global */
8512 LLVMDeleteGlobal (module->got_var);
8513 module->got_var = real_got;
8516 * Same for the init_var
8518 if (module->llvm_only) {
8519 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8520 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8521 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8522 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8523 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8524 LLVMDeleteGlobal (module->inited_var);
8527 if (module->llvm_only) {
8528 emit_get_method (&aot_module);
8529 emit_get_unbox_tramp (&aot_module);
8532 emit_llvm_used (&aot_module);
8533 emit_dbg_info (&aot_module, filename, cu_name);
8534 emit_aot_file_info (&aot_module);
8537 * Replace GOT entries for directly callable methods with the methods themselves.
8538 * It would be easier to implement this by predefining all methods before compiling
8539 * their bodies, but that couldn't handle the case when a method fails to compile
8542 if (module->llvm_only) {
8543 GHashTableIter iter;
8545 GSList *callers, *l;
8547 g_hash_table_iter_init (&iter, module->method_to_callers);
8548 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8549 LLVMValueRef lmethod;
8551 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8553 for (l = callers; l; l = l->next) {
8554 LLVMValueRef caller = (LLVMValueRef)l->data;
8556 mono_llvm_replace_uses_of (caller, lmethod);
8562 /* Replace PLT entries for directly callable methods with the methods themselves */
8564 GHashTableIter iter;
8566 LLVMValueRef callee;
8568 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8569 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8570 if (mono_aot_is_direct_callable (ji)) {
8571 LLVMValueRef lmethod;
8573 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8574 /* The types might not match because the caller might pass an rgctx */
8575 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8576 mono_llvm_replace_uses_of (callee, lmethod);
8577 mono_aot_mark_unused_llvm_plt_entry (ji);
8587 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8588 g_assert_not_reached ();
8593 LLVMWriteBitcodeToFile (module->lmodule, filename);
8598 md_string (const char *s)
8600 return LLVMMDString (s, strlen (s));
8603 /* Debugging support */
8606 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8608 LLVMModuleRef lmodule = module->lmodule;
8609 LLVMValueRef args [16], ver;
8612 * This can only be enabled when LLVM code is emitted into a separate object
8613 * file, since the AOT compiler also emits dwarf info,
8614 * and the abbrev indexes will not be correct since llvm has added its own
8617 if (!module->emit_dwarf)
8620 #if LLVM_API_VERSION > 100
8621 mono_llvm_di_builder_finalize (module->di_builder);
8623 LLVMValueRef cu_args [16], cu;
8625 char *build_info, *s, *dir;
8628 * Emit dwarf info in the form of LLVM metadata. There is some
8629 * out-of-date documentation at:
8630 * http://llvm.org/docs/SourceLevelDebugging.html
8631 * but most of this was gathered from the llvm and
8636 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8637 /* CU name/compilation dir */
8638 dir = g_path_get_dirname (filename);
8639 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8640 args [1] = LLVMMDString (dir, strlen (dir));
8641 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8644 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8646 build_info = mono_get_runtime_build_info ();
8647 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8648 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8649 g_free (build_info);
8651 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8653 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8654 /* Runtime version */
8655 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8657 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8658 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8660 if (module->subprogram_mds) {
8664 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8665 for (i = 0; i < module->subprogram_mds->len; ++i)
8666 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8667 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8669 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8672 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8673 /* Imported modules */
8674 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8676 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8677 /* DebugEmissionKind = FullDebug */
8678 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8679 cu = LLVMMDNode (cu_args, n_cuargs);
8680 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8683 #if LLVM_API_VERSION > 100
8684 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8685 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8686 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8687 ver = LLVMMDNode (args, 3);
8688 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8690 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8691 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8692 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8693 ver = LLVMMDNode (args, 3);
8694 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8696 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8697 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8698 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8699 ver = LLVMMDNode (args, 3);
8700 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8702 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8703 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8704 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8705 ver = LLVMMDNode (args, 3);
8706 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8711 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8713 MonoLLVMModule *module = ctx->module;
8714 MonoDebugMethodInfo *minfo = ctx->minfo;
8715 char *source_file, *dir, *filename;
8716 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8717 MonoSymSeqPoint *sym_seq_points;
8723 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8725 source_file = g_strdup ("<unknown>");
8726 dir = g_path_get_dirname (source_file);
8727 filename = g_path_get_basename (source_file);
8729 #if LLVM_API_VERSION > 100
8730 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8733 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8734 args [0] = md_string (filename);
8735 args [1] = md_string (dir);
8736 ctx_args [1] = LLVMMDNode (args, 2);
8737 ctx_md = LLVMMDNode (ctx_args, 2);
8739 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8740 type_args [1] = NULL;
8741 type_args [2] = NULL;
8742 type_args [3] = LLVMMDString ("", 0);
8743 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8744 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8745 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8746 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8747 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8748 type_args [9] = NULL;
8749 type_args [10] = NULL;
8750 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8751 type_args [12] = NULL;
8752 type_args [13] = NULL;
8753 type_args [14] = NULL;
8754 type_md = LLVMMDNode (type_args, 14);
8756 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8757 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8758 /* Source directory + file pair */
8759 args [0] = md_string (filename);
8760 args [1] = md_string (dir);
8761 md_args [1] = LLVMMDNode (args ,2);
8762 md_args [2] = ctx_md;
8763 md_args [3] = md_string (cfg->method->name);
8764 md_args [4] = md_string (name);
8765 md_args [5] = md_string (name);
8768 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8770 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8772 md_args [7] = type_md;
8774 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8776 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8778 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8779 /* Index into a virtual function */
8780 md_args [11] = NULL;
8781 md_args [12] = NULL;
8783 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8785 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8786 /* Pointer to LLVM function */
8787 md_args [15] = method;
8788 /* Function template parameter */
8789 md_args [16] = NULL;
8790 /* Function declaration descriptor */
8791 md_args [17] = NULL;
8792 /* List of function variables */
8793 md_args [18] = LLVMMDNode (args, 0);
8795 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8796 md = LLVMMDNode (md_args, 20);
8798 if (!module->subprogram_mds)
8799 module->subprogram_mds = g_ptr_array_new ();
8800 g_ptr_array_add (module->subprogram_mds, md);
8804 g_free (source_file);
8805 g_free (sym_seq_points);
8811 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8813 MonoCompile *cfg = ctx->cfg;
8815 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8816 MonoDebugSourceLocation *loc;
8817 LLVMValueRef loc_md;
8819 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8822 #if LLVM_API_VERSION > 100
8823 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8824 mono_llvm_di_set_location (builder, loc_md);
8826 LLVMValueRef md_args [16];
8830 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8831 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8832 md_args [nmd_args ++] = ctx->dbg_md;
8833 md_args [nmd_args ++] = NULL;
8834 loc_md = LLVMMDNode (md_args, nmd_args);
8835 LLVMSetCurrentDebugLocation (builder, loc_md);
8837 mono_debug_symfile_free_location (loc);
8843 default_mono_llvm_unhandled_exception (void)
8845 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8846 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8848 mono_unhandled_exception (target);
8849 exit (mono_environment_exitcode_get ());
8854 - Emit LLVM IR from the mono IR using the LLVM C API.
8855 - The original arch specific code remains, so we can fall back to it if we run
8856 into something we can't handle.
8860 A partial list of issues:
8861 - Handling of opcodes which can throw exceptions.
8863 In the mono JIT, these are implemented using code like this:
8870 push throw_pos - method
8871 call <exception trampoline>
8873 The problematic part is push throw_pos - method, which cannot be represented
8874 in the LLVM IR, since it does not support label values.
8875 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8876 be implemented in JIT mode ?
8877 -> a possible but slower implementation would use the normal exception
8878 throwing code but it would need to control the placement of the throw code
8879 (it needs to be exactly after the compare+branch).
8880 -> perhaps add a PC offset intrinsics ?
8882 - efficient implementation of .ovf opcodes.
8884 These are currently implemented as:
8885 <ins which sets the condition codes>
8888 Some overflow opcodes are now supported by LLVM SVN.
8890 - exception handling, unwinding.
8891 - SSA is disabled for methods with exception handlers
8892 - How to obtain unwind info for LLVM compiled methods ?
8893 -> this is now solved by converting the unwind info generated by LLVM
8895 - LLVM uses the c++ exception handling framework, while we use our home grown
8896 code, and couldn't use the c++ one:
8897 - its not supported under VC++, other exotic platforms.
8898 - it might be impossible to support filter clauses with it.
8902 The trampolines need a predictable call sequence, since they need to disasm
8903 the calling code to obtain register numbers / offsets.
8905 LLVM currently generates this code in non-JIT mode:
8906 mov -0x98(%rax),%eax
8908 Here, the vtable pointer is lost.
8909 -> solution: use one vtable trampoline per class.
8911 - passing/receiving the IMT pointer/RGCTX.
8912 -> solution: pass them as normal arguments ?
8916 LLVM does not allow the specification of argument registers etc. This means
8917 that all calls are made according to the platform ABI.
8919 - passing/receiving vtypes.
8921 Vtypes passed/received in registers are handled by the front end by using
8922 a signature with scalar arguments, and loading the parts of the vtype into those
8925 Vtypes passed on the stack are handled using the 'byval' attribute.
8929 Supported though alloca, we need to emit the load/store code.
8933 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8934 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8935 This is made easier because the IR is already in SSA form.
8936 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8937 types are frequently used incorrectly.
8942 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8943 it with the file containing the methods emitted by the JIT and the AOT data
8947 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8948 * - each bblock should end with a branch
8949 * - setting the return value, making cfg->ret non-volatile
8950 * - avoid some transformations in the JIT which make it harder for us to generate
8952 * - use pointer types to help optimizations.