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."
50 * Information associated by mono with LLVM modules.
53 LLVMModuleRef lmodule;
54 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
55 GHashTable *llvm_types;
57 const char *got_symbol;
58 const char *get_method_symbol;
59 const char *get_unbox_tramp_symbol;
60 GHashTable *plt_entries;
61 GHashTable *plt_entries_ji;
62 GHashTable *method_to_lmethod;
63 GHashTable *direct_callables;
68 GPtrArray *subprogram_mds;
70 LLVMExecutionEngineRef ee;
71 gboolean external_symbols;
76 MonoAssembly *assembly;
78 MonoAotFileInfo aot_info;
79 const char *jit_got_symbol;
80 const char *eh_frame_symbol;
81 LLVMValueRef get_method, get_unbox_tramp;
82 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
83 LLVMValueRef code_start, code_end;
84 LLVMValueRef inited_var;
85 int max_inited_idx, max_method_idx;
86 gboolean has_jitted_code;
89 GHashTable *idx_to_lmethod;
90 GHashTable *idx_to_unbox_tramp;
91 /* Maps a MonoMethod to LLVM instructions representing it */
92 GHashTable *method_to_callers;
93 LLVMContextRef context;
94 LLVMValueRef sentinel_exception;
95 void *di_builder, *cu;
99 * Information associated by the backend with mono basic blocks.
102 LLVMBasicBlockRef bblock, end_bblock;
103 LLVMValueRef finally_ind;
104 gboolean added, invoke_target;
106 * If this bblock is the start of a finally clause, this is a list of bblocks it
107 * needs to branch to in ENDFINALLY.
109 GSList *call_handler_return_bbs;
111 * If this bblock is the start of a finally clause, this is the bblock that
112 * CALL_HANDLER needs to branch to.
114 LLVMBasicBlockRef call_handler_target_bb;
115 /* The list of switch statements generated by ENDFINALLY instructions */
116 GSList *endfinally_switch_ins_list;
121 * Structure containing emit state
124 MonoMemPool *mempool;
126 /* Maps method names to the corresponding LLVMValueRef */
127 GHashTable *emitted_method_decls;
130 LLVMValueRef lmethod;
131 MonoLLVMModule *module;
132 LLVMModuleRef lmodule;
134 int sindex, default_index, ex_index;
135 LLVMBuilderRef builder;
136 LLVMValueRef *values, *addresses;
137 MonoType **vreg_cli_types;
139 MonoMethodSignature *sig;
141 GHashTable *region_to_handler;
142 GHashTable *clause_to_handler;
143 LLVMBuilderRef alloca_builder;
144 LLVMValueRef last_alloca;
145 LLVMValueRef rgctx_arg;
146 LLVMValueRef this_arg;
147 LLVMTypeRef *vreg_types;
148 LLVMTypeRef method_type;
149 LLVMBasicBlockRef init_bb, inited_bb;
151 gboolean *unreachable;
153 gboolean has_got_access;
154 gboolean is_linkonce;
155 int this_arg_pindex, rgctx_arg_pindex;
156 LLVMValueRef imt_rgctx_loc;
157 GHashTable *llvm_types;
159 MonoDebugMethodInfo *minfo;
161 /* For every clause, the clauses it is nested in */
164 GHashTable *exc_meta;
165 GHashTable *method_to_callers;
166 GPtrArray *phi_values;
167 GPtrArray *bblock_list;
174 MonoBasicBlock *in_bb;
179 * Instruction metadata
180 * This is the same as ins_info, but LREG != IREG.
188 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
189 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
196 /* keep in sync with the enum in mini.h */
199 #include "mini-ops.h"
204 #if SIZEOF_VOID_P == 4
205 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
207 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
210 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
213 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
215 #define TRACE_FAILURE(msg)
219 #define IS_TARGET_X86 1
221 #define IS_TARGET_X86 0
225 #define IS_TARGET_AMD64 1
227 #define IS_TARGET_AMD64 0
230 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
232 static LLVMIntPredicate cond_to_llvm_cond [] = {
245 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
258 static MonoNativeTlsKey current_cfg_tls_id;
260 static MonoLLVMModule aot_module;
261 static int memset_param_count, memcpy_param_count;
262 static const char *memset_func_name;
263 static const char *memcpy_func_name;
265 static void init_jit_module (MonoDomain *domain);
267 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
268 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
269 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
270 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
273 set_failure (EmitContext *ctx, const char *message)
275 TRACE_FAILURE (reason);
276 ctx->cfg->exception_message = g_strdup (message);
277 ctx->cfg->disable_llvm = TRUE;
283 * The LLVM type with width == sizeof (gpointer)
288 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
294 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
300 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
306 * Return the size of the LLVM representation of the vtype T.
309 get_vtype_size (MonoType *t)
313 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
315 /* LLVMArgAsIArgs depends on this since it stores whole words */
316 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
323 * simd_class_to_llvm_type:
325 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
328 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
330 if (!strcmp (klass->name, "Vector2d")) {
331 return LLVMVectorType (LLVMDoubleType (), 2);
332 } else if (!strcmp (klass->name, "Vector2l")) {
333 return LLVMVectorType (LLVMInt64Type (), 2);
334 } else if (!strcmp (klass->name, "Vector2ul")) {
335 return LLVMVectorType (LLVMInt64Type (), 2);
336 } else if (!strcmp (klass->name, "Vector4i")) {
337 return LLVMVectorType (LLVMInt32Type (), 4);
338 } else if (!strcmp (klass->name, "Vector4ui")) {
339 return LLVMVectorType (LLVMInt32Type (), 4);
340 } else if (!strcmp (klass->name, "Vector4f")) {
341 return LLVMVectorType (LLVMFloatType (), 4);
342 } else if (!strcmp (klass->name, "Vector8s")) {
343 return LLVMVectorType (LLVMInt16Type (), 8);
344 } else if (!strcmp (klass->name, "Vector8us")) {
345 return LLVMVectorType (LLVMInt16Type (), 8);
346 } else if (!strcmp (klass->name, "Vector16sb")) {
347 return LLVMVectorType (LLVMInt8Type (), 16);
348 } else if (!strcmp (klass->name, "Vector16b")) {
349 return LLVMVectorType (LLVMInt8Type (), 16);
351 printf ("%s\n", klass->name);
357 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
358 static inline G_GNUC_UNUSED LLVMTypeRef
359 type_to_simd_type (int type)
363 return LLVMVectorType (LLVMInt8Type (), 16);
365 return LLVMVectorType (LLVMInt16Type (), 8);
367 return LLVMVectorType (LLVMInt32Type (), 4);
369 return LLVMVectorType (LLVMInt64Type (), 2);
371 return LLVMVectorType (LLVMDoubleType (), 2);
373 return LLVMVectorType (LLVMFloatType (), 4);
375 g_assert_not_reached ();
381 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
383 int i, size, nfields, esize;
384 LLVMTypeRef *eltypes;
389 t = &klass->byval_arg;
391 if (mini_type_is_hfa (t, &nfields, &esize)) {
393 * This is needed on arm64 where HFAs are returned in
397 eltypes = g_new (LLVMTypeRef, size);
398 for (i = 0; i < size; ++i)
399 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
401 size = get_vtype_size (t);
403 eltypes = g_new (LLVMTypeRef, size);
404 for (i = 0; i < size; ++i)
405 eltypes [i] = LLVMInt8Type ();
408 name = mono_type_full_name (&klass->byval_arg);
409 ltype = LLVMStructCreateNamed (module->context, name);
410 LLVMStructSetBody (ltype, eltypes, size, FALSE);
420 * Return the LLVM type corresponding to T.
423 type_to_llvm_type (EmitContext *ctx, MonoType *t)
425 t = mini_get_underlying_type (t);
429 return LLVMVoidType ();
431 return LLVMInt8Type ();
433 return LLVMInt16Type ();
435 return LLVMInt32Type ();
437 return LLVMInt8Type ();
439 return LLVMInt16Type ();
441 return LLVMInt32Type ();
442 case MONO_TYPE_BOOLEAN:
443 return LLVMInt8Type ();
446 return LLVMInt64Type ();
448 return LLVMInt16Type ();
450 return LLVMFloatType ();
452 return LLVMDoubleType ();
455 return IntPtrType ();
456 case MONO_TYPE_OBJECT:
457 case MONO_TYPE_CLASS:
458 case MONO_TYPE_ARRAY:
459 case MONO_TYPE_SZARRAY:
460 case MONO_TYPE_STRING:
462 return ObjRefType ();
465 /* Because of generic sharing */
466 return ObjRefType ();
467 case MONO_TYPE_GENERICINST:
468 if (!mono_type_generic_inst_is_valuetype (t))
469 return ObjRefType ();
471 case MONO_TYPE_VALUETYPE:
472 case MONO_TYPE_TYPEDBYREF: {
476 klass = mono_class_from_mono_type (t);
478 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
479 return simd_class_to_llvm_type (ctx, klass);
482 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
484 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
486 ltype = create_llvm_type_for_type (ctx->module, klass);
487 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
493 printf ("X: %d\n", t->type);
494 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
495 ctx->cfg->disable_llvm = TRUE;
503 * Return whenever T is an unsigned int type.
506 type_is_unsigned (EmitContext *ctx, MonoType *t)
508 t = mini_get_underlying_type (t);
524 * type_to_llvm_arg_type:
526 * Same as type_to_llvm_type, but treat i8/i16 as i32.
529 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
531 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
533 if (ctx->cfg->llvm_only)
537 * This works on all abis except arm64/ios which passes multiple
538 * arguments in one stack slot.
541 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
543 * LLVM generates code which only sets the lower bits, while JITted
544 * code expects all the bits to be set.
546 ptype = LLVMInt32Type ();
554 * llvm_type_to_stack_type:
556 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
559 static G_GNUC_UNUSED LLVMTypeRef
560 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
564 if (type == LLVMInt8Type ())
565 return LLVMInt32Type ();
566 else if (type == LLVMInt16Type ())
567 return LLVMInt32Type ();
568 else if (!cfg->r4fp && type == LLVMFloatType ())
569 return LLVMDoubleType ();
575 * regtype_to_llvm_type:
577 * Return the LLVM type corresponding to the regtype C used in instruction
581 regtype_to_llvm_type (char c)
585 return LLVMInt32Type ();
587 return LLVMInt64Type ();
589 return LLVMDoubleType ();
598 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
601 op_to_llvm_type (int opcode)
606 return LLVMInt8Type ();
609 return LLVMInt8Type ();
612 return LLVMInt16Type ();
615 return LLVMInt16Type ();
618 return LLVMInt32Type ();
621 return LLVMInt32Type ();
623 return LLVMInt64Type ();
625 return LLVMFloatType ();
627 return LLVMDoubleType ();
629 return LLVMInt64Type ();
631 return LLVMInt32Type ();
633 return LLVMInt64Type ();
638 return LLVMInt8Type ();
643 return LLVMInt16Type ();
645 return LLVMInt32Type ();
648 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
655 return LLVMInt32Type ();
662 return LLVMInt64Type ();
664 printf ("%s\n", mono_inst_name (opcode));
665 g_assert_not_reached ();
670 #define CLAUSE_START(clause) ((clause)->try_offset)
671 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
674 * load_store_to_llvm_type:
676 * Return the size/sign/zero extension corresponding to the load/store opcode
680 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
686 case OP_LOADI1_MEMBASE:
687 case OP_STOREI1_MEMBASE_REG:
688 case OP_STOREI1_MEMBASE_IMM:
689 case OP_ATOMIC_LOAD_I1:
690 case OP_ATOMIC_STORE_I1:
693 return LLVMInt8Type ();
694 case OP_LOADU1_MEMBASE:
696 case OP_ATOMIC_LOAD_U1:
697 case OP_ATOMIC_STORE_U1:
700 return LLVMInt8Type ();
701 case OP_LOADI2_MEMBASE:
702 case OP_STOREI2_MEMBASE_REG:
703 case OP_STOREI2_MEMBASE_IMM:
704 case OP_ATOMIC_LOAD_I2:
705 case OP_ATOMIC_STORE_I2:
708 return LLVMInt16Type ();
709 case OP_LOADU2_MEMBASE:
711 case OP_ATOMIC_LOAD_U2:
712 case OP_ATOMIC_STORE_U2:
715 return LLVMInt16Type ();
716 case OP_LOADI4_MEMBASE:
717 case OP_LOADU4_MEMBASE:
720 case OP_STOREI4_MEMBASE_REG:
721 case OP_STOREI4_MEMBASE_IMM:
722 case OP_ATOMIC_LOAD_I4:
723 case OP_ATOMIC_STORE_I4:
724 case OP_ATOMIC_LOAD_U4:
725 case OP_ATOMIC_STORE_U4:
727 return LLVMInt32Type ();
728 case OP_LOADI8_MEMBASE:
730 case OP_STOREI8_MEMBASE_REG:
731 case OP_STOREI8_MEMBASE_IMM:
732 case OP_ATOMIC_LOAD_I8:
733 case OP_ATOMIC_STORE_I8:
734 case OP_ATOMIC_LOAD_U8:
735 case OP_ATOMIC_STORE_U8:
737 return LLVMInt64Type ();
738 case OP_LOADR4_MEMBASE:
739 case OP_STORER4_MEMBASE_REG:
740 case OP_ATOMIC_LOAD_R4:
741 case OP_ATOMIC_STORE_R4:
743 return LLVMFloatType ();
744 case OP_LOADR8_MEMBASE:
745 case OP_STORER8_MEMBASE_REG:
746 case OP_ATOMIC_LOAD_R8:
747 case OP_ATOMIC_STORE_R8:
749 return LLVMDoubleType ();
750 case OP_LOAD_MEMBASE:
752 case OP_STORE_MEMBASE_REG:
753 case OP_STORE_MEMBASE_IMM:
754 *size = sizeof (gpointer);
755 return IntPtrType ();
757 g_assert_not_reached ();
765 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
768 ovf_op_to_intrins (int opcode)
772 return "llvm.sadd.with.overflow.i32";
774 return "llvm.uadd.with.overflow.i32";
776 return "llvm.ssub.with.overflow.i32";
778 return "llvm.usub.with.overflow.i32";
780 return "llvm.smul.with.overflow.i32";
782 return "llvm.umul.with.overflow.i32";
784 return "llvm.sadd.with.overflow.i64";
786 return "llvm.uadd.with.overflow.i64";
788 return "llvm.ssub.with.overflow.i64";
790 return "llvm.usub.with.overflow.i64";
792 return "llvm.smul.with.overflow.i64";
794 return "llvm.umul.with.overflow.i64";
796 g_assert_not_reached ();
802 simd_op_to_intrins (int opcode)
805 #if defined(TARGET_X86) || defined(TARGET_AMD64)
807 return "llvm.x86.sse2.min.pd";
809 return "llvm.x86.sse.min.ps";
811 return "llvm.x86.sse41.pminud";
813 return "llvm.x86.sse41.pminuw";
815 return "llvm.x86.sse2.pminu.b";
817 return "llvm.x86.sse2.pmins.w";
819 return "llvm.x86.sse2.max.pd";
821 return "llvm.x86.sse.max.ps";
823 return "llvm.x86.sse3.hadd.pd";
825 return "llvm.x86.sse3.hadd.ps";
827 return "llvm.x86.sse3.hsub.pd";
829 return "llvm.x86.sse3.hsub.ps";
831 return "llvm.x86.sse41.pmaxud";
833 return "llvm.x86.sse41.pmaxuw";
835 return "llvm.x86.sse2.pmaxu.b";
837 return "llvm.x86.sse3.addsub.ps";
839 return "llvm.x86.sse3.addsub.pd";
840 case OP_EXTRACT_MASK:
841 return "llvm.x86.sse2.pmovmskb.128";
844 return "llvm.x86.sse2.psrli.w";
847 return "llvm.x86.sse2.psrli.d";
850 return "llvm.x86.sse2.psrli.q";
853 return "llvm.x86.sse2.pslli.w";
856 return "llvm.x86.sse2.pslli.d";
859 return "llvm.x86.sse2.pslli.q";
862 return "llvm.x86.sse2.psrai.w";
865 return "llvm.x86.sse2.psrai.d";
867 return "llvm.x86.sse2.padds.b";
869 return "llvm.x86.sse2.padds.w";
871 return "llvm.x86.sse2.psubs.b";
873 return "llvm.x86.sse2.psubs.w";
874 case OP_PADDB_SAT_UN:
875 return "llvm.x86.sse2.paddus.b";
876 case OP_PADDW_SAT_UN:
877 return "llvm.x86.sse2.paddus.w";
878 case OP_PSUBB_SAT_UN:
879 return "llvm.x86.sse2.psubus.b";
880 case OP_PSUBW_SAT_UN:
881 return "llvm.x86.sse2.psubus.w";
883 return "llvm.x86.sse2.pavg.b";
885 return "llvm.x86.sse2.pavg.w";
887 return "llvm.x86.sse.sqrt.ps";
889 return "llvm.x86.sse2.sqrt.pd";
891 return "llvm.x86.sse.rsqrt.ps";
893 return "llvm.x86.sse.rcp.ps";
895 return "llvm.x86.sse2.cvtdq2pd";
897 return "llvm.x86.sse2.cvtdq2ps";
899 return "llvm.x86.sse2.cvtpd2dq";
901 return "llvm.x86.sse2.cvtps2dq";
903 return "llvm.x86.sse2.cvtpd2ps";
905 return "llvm.x86.sse2.cvtps2pd";
907 return "llvm.x86.sse2.cvttpd2dq";
909 return "llvm.x86.sse2.cvttps2dq";
911 return "llvm.x86.sse.cmp.ps";
913 return "llvm.x86.sse2.cmp.pd";
915 return "llvm.x86.sse2.packsswb.128";
917 return "llvm.x86.sse2.packssdw.128";
919 return "llvm.x86.sse2.packuswb.128";
921 return "llvm.x86.sse41.packusdw";
923 return "llvm.x86.sse2.pmulh.w";
924 case OP_PMULW_HIGH_UN:
925 return "llvm.x86.sse2.pmulhu.w";
928 g_assert_not_reached ();
934 simd_op_to_llvm_type (int opcode)
936 #if defined(TARGET_X86) || defined(TARGET_AMD64)
940 return type_to_simd_type (MONO_TYPE_R8);
943 return type_to_simd_type (MONO_TYPE_I8);
946 return type_to_simd_type (MONO_TYPE_I4);
951 return type_to_simd_type (MONO_TYPE_I2);
955 return type_to_simd_type (MONO_TYPE_I1);
957 return type_to_simd_type (MONO_TYPE_R4);
960 return type_to_simd_type (MONO_TYPE_I4);
964 return type_to_simd_type (MONO_TYPE_R8);
968 return type_to_simd_type (MONO_TYPE_R4);
969 case OP_EXTRACT_MASK:
970 return type_to_simd_type (MONO_TYPE_I1);
976 return type_to_simd_type (MONO_TYPE_R4);
979 return type_to_simd_type (MONO_TYPE_R8);
981 g_assert_not_reached ();
992 * Return the LLVM basic block corresponding to BB.
994 static LLVMBasicBlockRef
995 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
997 char bb_name_buf [128];
1000 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1001 if (bb->flags & BB_EXCEPTION_HANDLER) {
1002 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1003 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1004 bb_name = bb_name_buf;
1005 } else if (bb->block_num < 256) {
1006 if (!ctx->module->bb_names) {
1007 ctx->module->bb_names_len = 256;
1008 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1010 if (!ctx->module->bb_names [bb->block_num]) {
1013 n = g_strdup_printf ("BB%d", bb->block_num);
1014 mono_memory_barrier ();
1015 ctx->module->bb_names [bb->block_num] = n;
1017 bb_name = ctx->module->bb_names [bb->block_num];
1019 sprintf (bb_name_buf, "BB%d", bb->block_num);
1020 bb_name = bb_name_buf;
1023 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1024 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1027 return ctx->bblocks [bb->block_num].bblock;
1033 * Return the last LLVM bblock corresponding to BB.
1034 * This might not be equal to the bb returned by get_bb () since we need to generate
1035 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1037 static LLVMBasicBlockRef
1038 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1041 return ctx->bblocks [bb->block_num].end_bblock;
1044 static LLVMBasicBlockRef
1045 gen_bb (EmitContext *ctx, const char *prefix)
1049 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1050 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1056 * Return the target of the patch identified by TYPE and TARGET.
1059 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1065 memset (&ji, 0, sizeof (ji));
1067 ji.data.target = target;
1069 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1070 mono_error_assert_ok (&error);
1078 * Emit code to convert the LLVM value V to DTYPE.
1081 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1083 LLVMTypeRef stype = LLVMTypeOf (v);
1085 if (stype != dtype) {
1086 gboolean ext = FALSE;
1089 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1091 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1093 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1097 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1099 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1100 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1103 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1104 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1105 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1106 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1107 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1108 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1109 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1110 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1112 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1113 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1114 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1115 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1117 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1119 if (mono_arch_is_soft_float ()) {
1120 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1121 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1122 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1123 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1126 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1127 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1130 LLVMDumpValue (LLVMConstNull (dtype));
1131 g_assert_not_reached ();
1139 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1141 return convert_full (ctx, v, dtype, FALSE);
1145 * emit_volatile_load:
1147 * If vreg is volatile, emit a load from its address.
1150 emit_volatile_load (EmitContext *ctx, int vreg)
1154 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1155 t = ctx->vreg_cli_types [vreg];
1156 if (t && !t->byref) {
1158 * Might have to zero extend since llvm doesn't have
1161 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1162 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1163 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1164 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1165 else if (t->type == MONO_TYPE_U8)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1173 * emit_volatile_store:
1175 * If VREG is volatile, emit a store from its value to its address.
1178 emit_volatile_store (EmitContext *ctx, int vreg)
1180 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1182 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1183 g_assert (ctx->addresses [vreg]);
1184 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1189 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1191 LLVMTypeRef ret_type;
1192 LLVMTypeRef *param_types = NULL;
1197 rtype = mini_get_underlying_type (sig->ret);
1198 ret_type = type_to_llvm_type (ctx, rtype);
1202 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1206 param_types [pindex ++] = ThisType ();
1207 for (i = 0; i < sig->param_count; ++i)
1208 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1210 if (!ctx_ok (ctx)) {
1211 g_free (param_types);
1215 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1216 g_free (param_types);
1222 * sig_to_llvm_sig_full:
1224 * Return the LLVM signature corresponding to the mono signature SIG using the
1225 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1228 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1230 LLVMTypeRef ret_type;
1231 LLVMTypeRef *param_types = NULL;
1233 int i, j, pindex, vret_arg_pindex = 0;
1234 gboolean vretaddr = FALSE;
1238 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1240 rtype = mini_get_underlying_type (sig->ret);
1241 ret_type = type_to_llvm_type (ctx, rtype);
1245 switch (cinfo->ret.storage) {
1246 case LLVMArgVtypeInReg:
1247 /* LLVM models this by returning an aggregate value */
1248 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1249 LLVMTypeRef members [2];
1251 members [0] = IntPtrType ();
1252 ret_type = LLVMStructType (members, 1, FALSE);
1253 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1255 ret_type = LLVMVoidType ();
1256 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1257 LLVMTypeRef members [2];
1259 members [0] = IntPtrType ();
1260 members [1] = IntPtrType ();
1261 ret_type = LLVMStructType (members, 2, FALSE);
1263 g_assert_not_reached ();
1266 case LLVMArgVtypeByVal:
1267 /* Vtype returned normally by val */
1269 case LLVMArgVtypeAsScalar: {
1270 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1271 /* LLVM models this by returning an int */
1272 if (size < SIZEOF_VOID_P) {
1273 g_assert (cinfo->ret.nslots == 1);
1274 ret_type = LLVMIntType (size * 8);
1276 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1277 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1281 case LLVMArgFpStruct: {
1282 /* Vtype returned as a fp struct */
1283 LLVMTypeRef members [16];
1285 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1286 for (i = 0; i < cinfo->ret.nslots; ++i)
1287 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1288 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1291 case LLVMArgVtypeByRef:
1292 /* Vtype returned using a hidden argument */
1293 ret_type = LLVMVoidType ();
1295 case LLVMArgVtypeRetAddr:
1296 case LLVMArgGsharedvtFixed:
1297 case LLVMArgGsharedvtFixedVtype:
1298 case LLVMArgGsharedvtVariable:
1300 ret_type = LLVMVoidType ();
1306 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1308 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1310 * Has to be the first argument because of the sret argument attribute
1311 * FIXME: This might conflict with passing 'this' as the first argument, but
1312 * this is only used on arm64 which has a dedicated struct return register.
1314 cinfo->vret_arg_pindex = pindex;
1315 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1316 if (!ctx_ok (ctx)) {
1317 g_free (param_types);
1320 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1323 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1324 cinfo->rgctx_arg_pindex = pindex;
1325 param_types [pindex] = ctx->module->ptr_type;
1328 if (cinfo->imt_arg) {
1329 cinfo->imt_arg_pindex = pindex;
1330 param_types [pindex] = ctx->module->ptr_type;
1334 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1335 vret_arg_pindex = pindex;
1336 if (cinfo->vret_arg_index == 1) {
1337 /* Add the slots consumed by the first argument */
1338 LLVMArgInfo *ainfo = &cinfo->args [0];
1339 switch (ainfo->storage) {
1340 case LLVMArgVtypeInReg:
1341 for (j = 0; j < 2; ++j) {
1342 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1351 cinfo->vret_arg_pindex = vret_arg_pindex;
1354 if (vretaddr && vret_arg_pindex == pindex)
1355 param_types [pindex ++] = IntPtrType ();
1357 cinfo->this_arg_pindex = pindex;
1358 param_types [pindex ++] = ThisType ();
1359 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1361 if (vretaddr && vret_arg_pindex == pindex)
1362 param_types [pindex ++] = IntPtrType ();
1363 for (i = 0; i < sig->param_count; ++i) {
1364 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1366 if (vretaddr && vret_arg_pindex == pindex)
1367 param_types [pindex ++] = IntPtrType ();
1368 ainfo->pindex = pindex;
1370 switch (ainfo->storage) {
1371 case LLVMArgVtypeInReg:
1372 for (j = 0; j < 2; ++j) {
1373 switch (ainfo->pair_storage [j]) {
1375 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1380 g_assert_not_reached ();
1384 case LLVMArgVtypeByVal:
1385 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1388 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1391 case LLVMArgAsIArgs:
1392 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1395 case LLVMArgVtypeByRef:
1396 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1399 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1402 case LLVMArgAsFpArgs: {
1405 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1406 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1407 param_types [pindex ++] = LLVMDoubleType ();
1408 for (j = 0; j < ainfo->nslots; ++j)
1409 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1412 case LLVMArgVtypeAsScalar:
1413 g_assert_not_reached ();
1415 case LLVMArgGsharedvtFixed:
1416 case LLVMArgGsharedvtFixedVtype:
1417 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1419 case LLVMArgGsharedvtVariable:
1420 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1423 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 if (!ctx_ok (ctx)) {
1428 g_free (param_types);
1431 if (vretaddr && vret_arg_pindex == pindex)
1432 param_types [pindex ++] = IntPtrType ();
1433 if (ctx->llvm_only && cinfo->rgctx_arg) {
1434 /* Pass the rgctx as the last argument */
1435 cinfo->rgctx_arg_pindex = pindex;
1436 param_types [pindex] = ctx->module->ptr_type;
1440 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1441 g_free (param_types);
1447 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1449 return sig_to_llvm_sig_full (ctx, sig, NULL);
1453 * LLVMFunctionType1:
1455 * Create an LLVM function type from the arguments.
1457 static G_GNUC_UNUSED LLVMTypeRef
1458 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1461 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1465 * LLVMFunctionType1:
1467 * Create an LLVM function type from the arguments.
1469 static G_GNUC_UNUSED LLVMTypeRef
1470 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1471 LLVMTypeRef ParamType1,
1474 LLVMTypeRef param_types [1];
1476 param_types [0] = ParamType1;
1478 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1482 * LLVMFunctionType2:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1492 LLVMTypeRef param_types [2];
1494 param_types [0] = ParamType1;
1495 param_types [1] = ParamType2;
1497 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1501 * LLVMFunctionType3:
1503 * Create an LLVM function type from the arguments.
1505 static G_GNUC_UNUSED LLVMTypeRef
1506 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1507 LLVMTypeRef ParamType1,
1508 LLVMTypeRef ParamType2,
1509 LLVMTypeRef ParamType3,
1512 LLVMTypeRef param_types [3];
1514 param_types [0] = ParamType1;
1515 param_types [1] = ParamType2;
1516 param_types [2] = ParamType3;
1518 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1521 static G_GNUC_UNUSED LLVMTypeRef
1522 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1523 LLVMTypeRef ParamType1,
1524 LLVMTypeRef ParamType2,
1525 LLVMTypeRef ParamType3,
1526 LLVMTypeRef ParamType4,
1527 LLVMTypeRef ParamType5,
1530 LLVMTypeRef param_types [5];
1532 param_types [0] = ParamType1;
1533 param_types [1] = ParamType2;
1534 param_types [2] = ParamType3;
1535 param_types [3] = ParamType4;
1536 param_types [4] = ParamType5;
1538 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1544 * Create an LLVM builder and remember it so it can be freed later.
1546 static LLVMBuilderRef
1547 create_builder (EmitContext *ctx)
1549 LLVMBuilderRef builder = LLVMCreateBuilder ();
1551 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1557 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1562 case MONO_PATCH_INFO_INTERNAL_METHOD:
1563 name = g_strdup_printf ("jit_icall_%s", data);
1565 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1566 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1567 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1571 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1579 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1583 LLVMValueRef indexes [2];
1585 LLVMValueRef got_entry_addr, load;
1586 LLVMBuilderRef builder = ctx->builder;
1591 ji = g_new0 (MonoJumpInfo, 1);
1593 ji->data.target = data;
1595 ji = mono_aot_patch_info_dup (ji);
1597 ji->next = cfg->patch_info;
1598 cfg->patch_info = ji;
1600 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1601 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1603 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1604 * explicitly initialize it.
1606 if (!mono_aot_is_shared_got_offset (got_offset)) {
1607 //mono_print_ji (ji);
1609 ctx->has_got_access = TRUE;
1612 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1613 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1614 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1616 name = get_aotconst_name (type, data, got_offset);
1618 load = LLVMBuildLoad (builder, got_entry_addr, "");
1619 load = convert (ctx, load, llvm_type);
1620 LLVMSetValueName (load, name ? name : "");
1622 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1625 //set_invariant_load_flag (load);
1631 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1633 return get_aotconst_typed (ctx, type, data, NULL);
1637 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1639 LLVMValueRef callee;
1641 if (ctx->llvm_only) {
1642 callee_name = mono_aot_get_direct_call_symbol (type, data);
1644 /* Directly callable */
1646 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1648 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1650 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1652 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1654 /* LLVMTypeRef's are uniqued */
1655 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1656 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1658 g_free (callee_name);
1664 * Calls are made through the GOT.
1666 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1668 MonoJumpInfo *ji = NULL;
1670 callee_name = mono_aot_get_plt_symbol (type, data);
1674 if (ctx->cfg->compile_aot)
1675 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1676 mono_add_patch_info (ctx->cfg, 0, type, data);
1679 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1681 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1683 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1685 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1688 if (ctx->cfg->compile_aot) {
1689 ji = g_new0 (MonoJumpInfo, 1);
1691 ji->data.target = data;
1693 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1701 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1703 MonoMethodHeader *header = cfg->header;
1704 MonoExceptionClause *clause;
1708 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1709 return (bb->region >> 8) - 1;
1712 for (i = 0; i < header->num_clauses; ++i) {
1713 clause = &header->clauses [i];
1715 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1722 static MonoExceptionClause *
1723 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1725 // Since they're sorted by nesting we just need
1726 // the first one that the bb is a member of
1727 MonoExceptionClause *last = NULL;
1729 for (int i = 0; i < cfg->header->num_clauses; i++) {
1730 MonoExceptionClause *curr = &cfg->header->clauses [i];
1732 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1735 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1736 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1750 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1752 LLVMValueRef md_arg;
1755 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1756 md_arg = LLVMMDString ("mono", 4);
1757 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1761 set_invariant_load_flag (LLVMValueRef v)
1763 LLVMValueRef md_arg;
1765 const char *flag_name;
1767 // FIXME: Cache this
1768 flag_name = "invariant.load";
1769 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1770 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1771 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1777 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1781 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1783 MonoCompile *cfg = ctx->cfg;
1784 LLVMValueRef lcall = NULL;
1785 LLVMBuilderRef builder = *builder_ref;
1786 MonoExceptionClause *clause;
1788 if (ctx->llvm_only) {
1789 clause = get_most_deep_clause (cfg, ctx, bb);
1792 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1795 * Have to use an invoke instead of a call, branching to the
1796 * handler bblock of the clause containing this bblock.
1798 intptr_t key = CLAUSE_END(clause);
1800 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1802 // FIXME: Find the one that has the lowest end bound for the right start address
1803 // FIXME: Finally + nesting
1806 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1809 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1811 builder = ctx->builder = create_builder (ctx);
1812 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1814 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1818 int clause_index = get_handler_clause (cfg, bb);
1820 if (clause_index != -1) {
1821 MonoMethodHeader *header = cfg->header;
1822 MonoExceptionClause *ec = &header->clauses [clause_index];
1823 MonoBasicBlock *tblock;
1824 LLVMBasicBlockRef ex_bb, noex_bb;
1827 * Have to use an invoke instead of a call, branching to the
1828 * handler bblock of the clause containing this bblock.
1831 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1833 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1836 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1838 ex_bb = get_bb (ctx, tblock);
1840 noex_bb = gen_bb (ctx, "NOEX_BB");
1843 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1845 builder = ctx->builder = create_builder (ctx);
1846 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1848 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1853 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1854 ctx->builder = builder;
1858 *builder_ref = ctx->builder;
1864 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1866 const char *intrins_name;
1867 LLVMValueRef args [16], res;
1868 LLVMTypeRef addr_type;
1869 gboolean use_intrinsics = TRUE;
1871 #if LLVM_API_VERSION > 100
1872 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1873 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1874 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1875 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1876 *builder_ref = ctx->builder;
1877 use_intrinsics = FALSE;
1881 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1882 LLVMAtomicOrdering ordering;
1885 case LLVM_BARRIER_NONE:
1886 ordering = LLVMAtomicOrderingNotAtomic;
1888 case LLVM_BARRIER_ACQ:
1889 ordering = LLVMAtomicOrderingAcquire;
1891 case LLVM_BARRIER_SEQ:
1892 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1895 g_assert_not_reached ();
1900 * We handle loads which can fault by calling a mono specific intrinsic
1901 * using an invoke, so they are handled properly inside try blocks.
1902 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1903 * are marked with IntrReadArgMem.
1907 intrins_name = "llvm.mono.load.i8.p0i8";
1910 intrins_name = "llvm.mono.load.i16.p0i16";
1913 intrins_name = "llvm.mono.load.i32.p0i32";
1916 intrins_name = "llvm.mono.load.i64.p0i64";
1919 g_assert_not_reached ();
1922 addr_type = LLVMTypeOf (addr);
1923 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1924 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1927 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1928 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1929 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1930 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1932 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1933 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1934 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1942 * We emit volatile loads for loads which can fault, because otherwise
1943 * LLVM will generate invalid code when encountering a load from a
1946 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1948 /* Mark it with a custom metadata */
1951 set_metadata_flag (res, "mono.faulting.load");
1959 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1961 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1965 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1967 const char *intrins_name;
1968 LLVMValueRef args [16];
1969 gboolean use_intrinsics = TRUE;
1971 #if LLVM_API_VERSION > 100
1972 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1973 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1974 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1975 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1976 *builder_ref = ctx->builder;
1977 use_intrinsics = FALSE;
1981 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1982 LLVMAtomicOrdering ordering;
1985 case LLVM_BARRIER_NONE:
1986 ordering = LLVMAtomicOrderingNotAtomic;
1988 case LLVM_BARRIER_REL:
1989 ordering = LLVMAtomicOrderingRelease;
1991 case LLVM_BARRIER_SEQ:
1992 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1995 g_assert_not_reached ();
2001 intrins_name = "llvm.mono.store.i8.p0i8";
2004 intrins_name = "llvm.mono.store.i16.p0i16";
2007 intrins_name = "llvm.mono.store.i32.p0i32";
2010 intrins_name = "llvm.mono.store.i64.p0i64";
2013 g_assert_not_reached ();
2016 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2017 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2018 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2023 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2024 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2025 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2026 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2028 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2033 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2035 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2039 * emit_cond_system_exception:
2041 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2042 * Might set the ctx exception.
2045 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2047 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2048 LLVMBuilderRef builder;
2049 MonoClass *exc_class;
2050 LLVMValueRef args [2];
2051 LLVMValueRef callee;
2053 ex_bb = gen_bb (ctx, "EX_BB");
2055 ex2_bb = gen_bb (ctx, "EX2_BB");
2056 noex_bb = gen_bb (ctx, "NOEX_BB");
2058 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2060 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2062 /* Emit exception throwing code */
2063 ctx->builder = builder = create_builder (ctx);
2064 LLVMPositionBuilderAtEnd (builder, ex_bb);
2066 if (ctx->cfg->llvm_only) {
2067 static LLVMTypeRef sig;
2070 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2071 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2073 LLVMBuildBr (builder, ex2_bb);
2075 ctx->builder = builder = create_builder (ctx);
2076 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2078 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2079 emit_call (ctx, bb, &builder, callee, args, 1);
2080 LLVMBuildUnreachable (builder);
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2085 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2091 callee = ctx->module->throw_corlib_exception;
2094 const char *icall_name;
2096 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2097 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2099 if (ctx->cfg->compile_aot) {
2100 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2102 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2105 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2106 * - On x86, LLVM generated code doesn't push the arguments
2107 * - The trampoline takes the throw address as an arguments, not a pc offset.
2109 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2111 mono_memory_barrier ();
2112 ctx->module->throw_corlib_exception = callee;
2116 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2117 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2119 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2122 * The LLVM mono branch contains changes so a block address can be passed as an
2123 * argument to a call.
2125 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2126 emit_call (ctx, bb, &builder, callee, args, 2);
2128 LLVMBuildUnreachable (builder);
2130 ctx->builder = builder = create_builder (ctx);
2131 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2133 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2140 * emit_args_to_vtype:
2142 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2145 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2147 int j, size, nslots;
2149 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2151 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2152 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2155 if (ainfo->storage == LLVMArgAsFpArgs)
2156 nslots = ainfo->nslots;
2160 for (j = 0; j < nslots; ++j) {
2161 LLVMValueRef index [2], addr, daddr;
2162 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2163 LLVMTypeRef part_type;
2165 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2168 if (ainfo->pair_storage [j] == LLVMArgNone)
2171 switch (ainfo->pair_storage [j]) {
2172 case LLVMArgInIReg: {
2173 part_type = LLVMIntType (part_size * 8);
2174 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2175 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2176 addr = LLVMBuildGEP (builder, address, index, 1, "");
2178 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2179 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2180 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2182 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2185 case LLVMArgInFPReg: {
2186 LLVMTypeRef arg_type;
2188 if (ainfo->esize == 8)
2189 arg_type = LLVMDoubleType ();
2191 arg_type = LLVMFloatType ();
2193 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2194 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2195 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2196 LLVMBuildStore (builder, args [j], addr);
2202 g_assert_not_reached ();
2205 size -= sizeof (gpointer);
2210 * emit_vtype_to_args:
2212 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2213 * into ARGS, and the number of arguments into NARGS.
2216 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2219 int j, size, nslots;
2220 LLVMTypeRef arg_type;
2222 size = get_vtype_size (t);
2224 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2225 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2227 if (ainfo->storage == LLVMArgAsFpArgs)
2228 nslots = ainfo->nslots;
2231 for (j = 0; j < nslots; ++j) {
2232 LLVMValueRef index [2], addr, daddr;
2233 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2235 if (ainfo->pair_storage [j] == LLVMArgNone)
2238 switch (ainfo->pair_storage [j]) {
2240 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2241 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2242 addr = LLVMBuildGEP (builder, address, index, 1, "");
2244 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2245 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2246 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2248 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2250 case LLVMArgInFPReg:
2251 if (ainfo->esize == 8)
2252 arg_type = LLVMDoubleType ();
2254 arg_type = LLVMFloatType ();
2255 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2256 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2257 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2258 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2263 g_assert_not_reached ();
2265 size -= sizeof (gpointer);
2272 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2275 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2276 * get executed every time control reaches them.
2278 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2280 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2281 return ctx->last_alloca;
2285 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2287 return build_alloca_llvm_type_name (ctx, t, align, "");
2291 build_alloca (EmitContext *ctx, MonoType *t)
2293 MonoClass *k = mono_class_from_mono_type (t);
2296 g_assert (!mini_is_gsharedvt_variable_type (t));
2298 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2301 align = mono_class_min_align (k);
2303 /* Sometimes align is not a power of 2 */
2304 while (mono_is_power_of_two (align) == -1)
2307 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2311 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2315 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2317 MonoCompile *cfg = ctx->cfg;
2318 LLVMBuilderRef builder = ctx->builder;
2319 LLVMValueRef offset, offset_var;
2320 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2321 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2325 g_assert (info_var);
2326 g_assert (locals_var);
2328 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2330 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2331 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2333 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2334 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2336 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2340 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2343 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2346 module->used = g_ptr_array_sized_new (16);
2347 g_ptr_array_add (module->used, global);
2351 emit_llvm_used (MonoLLVMModule *module)
2353 LLVMModuleRef lmodule = module->lmodule;
2354 LLVMTypeRef used_type;
2355 LLVMValueRef used, *used_elem;
2361 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2362 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2363 used_elem = g_new0 (LLVMValueRef, module->used->len);
2364 for (i = 0; i < module->used->len; ++i)
2365 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2366 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2367 LLVMSetLinkage (used, LLVMAppendingLinkage);
2368 LLVMSetSection (used, "llvm.metadata");
2374 * Emit a function mapping method indexes to their code
2377 emit_get_method (MonoLLVMModule *module)
2379 LLVMModuleRef lmodule = module->lmodule;
2380 LLVMValueRef func, switch_ins, m;
2381 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2382 LLVMBasicBlockRef *bbs;
2384 LLVMBuilderRef builder;
2389 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2390 * but generating code seems safer.
2392 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2393 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2394 LLVMSetLinkage (func, LLVMExternalLinkage);
2395 LLVMSetVisibility (func, LLVMHiddenVisibility);
2396 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2397 module->get_method = func;
2399 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2402 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2403 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2404 * then we will have to find another solution.
2407 name = g_strdup_printf ("BB_CODE_START");
2408 code_start_bb = LLVMAppendBasicBlock (func, name);
2410 builder = LLVMCreateBuilder ();
2411 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2412 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2414 name = g_strdup_printf ("BB_CODE_END");
2415 code_end_bb = LLVMAppendBasicBlock (func, name);
2417 builder = LLVMCreateBuilder ();
2418 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2419 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2421 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2422 for (i = 0; i < module->max_method_idx + 1; ++i) {
2423 name = g_strdup_printf ("BB_%d", i);
2424 bb = LLVMAppendBasicBlock (func, name);
2428 builder = LLVMCreateBuilder ();
2429 LLVMPositionBuilderAtEnd (builder, bb);
2431 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2433 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2435 LLVMBuildRet (builder, LLVMConstNull (rtype));
2438 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2439 builder = LLVMCreateBuilder ();
2440 LLVMPositionBuilderAtEnd (builder, fail_bb);
2441 LLVMBuildRet (builder, LLVMConstNull (rtype));
2443 builder = LLVMCreateBuilder ();
2444 LLVMPositionBuilderAtEnd (builder, entry_bb);
2446 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2447 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2448 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2449 for (i = 0; i < module->max_method_idx + 1; ++i) {
2450 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2453 mark_as_used (module, func);
2457 * emit_get_unbox_tramp:
2459 * Emit a function mapping method indexes to their unbox trampoline
2462 emit_get_unbox_tramp (MonoLLVMModule *module)
2464 LLVMModuleRef lmodule = module->lmodule;
2465 LLVMValueRef func, switch_ins, m;
2466 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2467 LLVMBasicBlockRef *bbs;
2469 LLVMBuilderRef builder;
2473 /* Similar to emit_get_method () */
2475 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2476 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2477 LLVMSetLinkage (func, LLVMExternalLinkage);
2478 LLVMSetVisibility (func, LLVMHiddenVisibility);
2479 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2480 module->get_unbox_tramp = func;
2482 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2484 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2485 for (i = 0; i < module->max_method_idx + 1; ++i) {
2486 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2490 name = g_strdup_printf ("BB_%d", i);
2491 bb = LLVMAppendBasicBlock (func, name);
2495 builder = LLVMCreateBuilder ();
2496 LLVMPositionBuilderAtEnd (builder, bb);
2498 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2501 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2502 builder = LLVMCreateBuilder ();
2503 LLVMPositionBuilderAtEnd (builder, fail_bb);
2504 LLVMBuildRet (builder, LLVMConstNull (rtype));
2506 builder = LLVMCreateBuilder ();
2507 LLVMPositionBuilderAtEnd (builder, entry_bb);
2509 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2510 for (i = 0; i < module->max_method_idx + 1; ++i) {
2511 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2518 mark_as_used (module, func);
2521 /* Add a function to mark the beginning of LLVM code */
2523 emit_llvm_code_start (MonoLLVMModule *module)
2525 LLVMModuleRef lmodule = module->lmodule;
2527 LLVMBasicBlockRef entry_bb;
2528 LLVMBuilderRef builder;
2530 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2531 LLVMSetLinkage (func, LLVMInternalLinkage);
2532 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2533 module->code_start = func;
2534 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2537 LLVMBuildRetVoid (builder);
2541 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2543 LLVMModuleRef lmodule = module->lmodule;
2544 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2545 LLVMBasicBlockRef entry_bb;
2546 LLVMBuilderRef builder;
2553 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2554 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2559 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2560 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2563 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2564 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2567 g_assert_not_reached ();
2569 LLVMSetLinkage (func, LLVMInternalLinkage);
2570 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2571 mono_llvm_set_preserveall_cc (func);
2572 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2573 builder = LLVMCreateBuilder ();
2574 LLVMPositionBuilderAtEnd (builder, entry_bb);
2577 ji = g_new0 (MonoJumpInfo, 1);
2578 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2579 ji = mono_aot_patch_info_dup (ji);
2580 got_offset = mono_aot_get_got_offset (ji);
2581 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2582 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2583 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2584 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2585 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2586 args [1] = LLVMGetParam (func, 0);
2588 args [2] = LLVMGetParam (func, 1);
2590 ji = g_new0 (MonoJumpInfo, 1);
2591 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2592 ji->data.name = icall_name;
2593 ji = mono_aot_patch_info_dup (ji);
2594 got_offset = mono_aot_get_got_offset (ji);
2595 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2596 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2597 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2598 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2599 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2600 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2601 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2603 // Set the inited flag
2604 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2605 indexes [1] = LLVMGetParam (func, 0);
2606 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2608 LLVMBuildRetVoid (builder);
2610 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2615 * Emit wrappers around the C icalls used to initialize llvm methods, to
2616 * make the calling code smaller and to enable usage of the llvm
2617 * PreserveAll calling convention.
2620 emit_init_icall_wrappers (MonoLLVMModule *module)
2622 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2623 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2624 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2625 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2629 emit_llvm_code_end (MonoLLVMModule *module)
2631 LLVMModuleRef lmodule = module->lmodule;
2633 LLVMBasicBlockRef entry_bb;
2634 LLVMBuilderRef builder;
2636 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2637 LLVMSetLinkage (func, LLVMInternalLinkage);
2638 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2639 module->code_end = func;
2640 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2641 builder = LLVMCreateBuilder ();
2642 LLVMPositionBuilderAtEnd (builder, entry_bb);
2643 LLVMBuildRetVoid (builder);
2647 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2649 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2652 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2653 need_div_check = TRUE;
2655 if (!need_div_check)
2658 switch (ins->opcode) {
2671 case OP_IDIV_UN_IMM:
2672 case OP_LDIV_UN_IMM:
2673 case OP_IREM_UN_IMM:
2674 case OP_LREM_UN_IMM: {
2676 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2677 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2679 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2680 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2683 builder = ctx->builder;
2685 /* b == -1 && a == 0x80000000 */
2687 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2688 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2689 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2691 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2692 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2695 builder = ctx->builder;
2707 * Emit code to initialize the GOT slots used by the method.
2710 emit_init_method (EmitContext *ctx)
2712 LLVMValueRef indexes [16], args [16], callee;
2713 LLVMValueRef inited_var, cmp, call;
2714 LLVMBasicBlockRef inited_bb, notinited_bb;
2715 LLVMBuilderRef builder = ctx->builder;
2716 MonoCompile *cfg = ctx->cfg;
2718 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2720 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2721 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2722 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2724 args [0] = inited_var;
2725 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2726 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2728 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2730 inited_bb = ctx->inited_bb;
2731 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2733 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2735 builder = ctx->builder = create_builder (ctx);
2736 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2739 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2740 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2741 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2742 callee = ctx->module->init_method_gshared_mrgctx;
2743 call = LLVMBuildCall (builder, callee, args, 2, "");
2744 } else if (ctx->rgctx_arg) {
2745 /* A vtable is passed as the rgctx argument */
2746 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2747 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2748 callee = ctx->module->init_method_gshared_vtable;
2749 call = LLVMBuildCall (builder, callee, args, 2, "");
2750 } else if (cfg->gshared) {
2751 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2752 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2753 callee = ctx->module->init_method_gshared_this;
2754 call = LLVMBuildCall (builder, callee, args, 2, "");
2756 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2757 callee = ctx->module->init_method;
2758 call = LLVMBuildCall (builder, callee, args, 1, "");
2762 * This enables llvm to keep arguments in their original registers/
2763 * scratch registers, since the call will not clobber them.
2765 mono_llvm_set_call_preserveall_cc (call);
2767 LLVMBuildBr (builder, inited_bb);
2768 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2770 builder = ctx->builder = create_builder (ctx);
2771 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2775 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2778 * Emit unbox trampoline using a tail call
2780 LLVMValueRef tramp, call, *args;
2781 LLVMBuilderRef builder;
2782 LLVMBasicBlockRef lbb;
2783 LLVMCallInfo *linfo;
2787 tramp_name = g_strdup_printf ("ut_%s", method_name);
2788 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2789 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2790 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2791 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2793 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2794 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2795 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2796 if (ctx->cfg->vret_addr) {
2797 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2798 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2799 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2800 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2804 lbb = LLVMAppendBasicBlock (tramp, "");
2805 builder = LLVMCreateBuilder ();
2806 LLVMPositionBuilderAtEnd (builder, lbb);
2808 nargs = LLVMCountParamTypes (method_type);
2809 args = g_new0 (LLVMValueRef, nargs);
2810 for (i = 0; i < nargs; ++i) {
2811 args [i] = LLVMGetParam (tramp, i);
2812 if (i == ctx->this_arg_pindex) {
2813 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2815 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2816 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2817 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2820 call = LLVMBuildCall (builder, method, args, nargs, "");
2821 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2822 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2823 if (linfo->ret.storage == LLVMArgVtypeByRef)
2824 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2826 // FIXME: This causes assertions in clang
2827 //mono_llvm_set_must_tail (call);
2828 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2829 LLVMBuildRetVoid (builder);
2831 LLVMBuildRet (builder, call);
2833 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2839 * Emit code to load/convert arguments.
2842 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2845 MonoCompile *cfg = ctx->cfg;
2846 MonoMethodSignature *sig = ctx->sig;
2847 LLVMCallInfo *linfo = ctx->linfo;
2851 LLVMBuilderRef old_builder = ctx->builder;
2852 ctx->builder = builder;
2854 ctx->alloca_builder = create_builder (ctx);
2857 * Handle indirect/volatile variables by allocating memory for them
2858 * using 'alloca', and storing their address in a temporary.
2860 for (i = 0; i < cfg->num_varinfo; ++i) {
2861 MonoInst *var = cfg->varinfo [i];
2864 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2865 } 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))) {
2866 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2869 /* Could be already created by an OP_VPHI */
2870 if (!ctx->addresses [var->dreg]) {
2871 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2872 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2874 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2878 names = g_new (char *, sig->param_count);
2879 mono_method_get_param_names (cfg->method, (const char **) names);
2881 for (i = 0; i < sig->param_count; ++i) {
2882 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2883 int reg = cfg->args [i + sig->hasthis]->dreg;
2886 pindex = ainfo->pindex;
2888 switch (ainfo->storage) {
2889 case LLVMArgVtypeInReg:
2890 case LLVMArgAsFpArgs: {
2891 LLVMValueRef args [8];
2894 pindex += ainfo->ndummy_fpargs;
2896 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2897 memset (args, 0, sizeof (args));
2898 if (ainfo->storage == LLVMArgVtypeInReg) {
2899 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2900 if (ainfo->pair_storage [1] != LLVMArgNone)
2901 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2903 g_assert (ainfo->nslots <= 8);
2904 for (j = 0; j < ainfo->nslots; ++j)
2905 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2907 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2909 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2911 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2912 /* Treat these as normal values */
2913 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2917 case LLVMArgVtypeByVal: {
2918 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2920 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2921 /* Treat these as normal values */
2922 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2926 case LLVMArgVtypeByRef: {
2927 /* The argument is passed by ref */
2928 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2931 case LLVMArgAsIArgs: {
2932 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2935 /* The argument is received as an array of ints, store it into the real argument */
2936 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2938 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2939 if (size < SIZEOF_VOID_P) {
2940 /* The upper bits of the registers might not be valid */
2941 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2942 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2943 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2945 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2949 case LLVMArgVtypeAsScalar:
2950 g_assert_not_reached ();
2952 case LLVMArgGsharedvtFixed: {
2953 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2954 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2957 name = g_strdup_printf ("arg_%s", names [i]);
2959 name = g_strdup_printf ("arg_%d", i);
2961 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2964 case LLVMArgGsharedvtFixedVtype: {
2965 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2968 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2970 name = g_strdup_printf ("vtype_arg_%d", i);
2972 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2973 g_assert (ctx->addresses [reg]);
2974 LLVMSetValueName (ctx->addresses [reg], name);
2975 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2978 case LLVMArgGsharedvtVariable:
2979 /* The IR treats these as variables with addresses */
2980 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2983 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));
2990 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2992 emit_volatile_store (ctx, cfg->args [0]->dreg);
2993 for (i = 0; i < sig->param_count; ++i)
2994 if (!mini_type_is_vtype (sig->params [i]))
2995 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2997 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2998 LLVMValueRef this_alloc;
3001 * The exception handling code needs the location where the this argument was
3002 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3003 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3004 * location into the LSDA.
3006 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3007 /* This volatile store will keep the alloca alive */
3008 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3010 set_metadata_flag (this_alloc, "mono.this");
3013 if (cfg->rgctx_var) {
3014 LLVMValueRef rgctx_alloc, store;
3017 * We handle the rgctx arg similarly to the this pointer.
3019 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3020 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3021 /* This volatile store will keep the alloca alive */
3022 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3024 set_metadata_flag (rgctx_alloc, "mono.this");
3027 /* Initialize the method if needed */
3028 if (cfg->compile_aot && ctx->llvm_only) {
3029 /* Emit a location for the initialization code */
3030 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3031 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3033 LLVMBuildBr (ctx->builder, ctx->init_bb);
3034 builder = ctx->builder = create_builder (ctx);
3035 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3036 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3039 /* Compute nesting between clauses */
3040 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3041 for (i = 0; i < cfg->header->num_clauses; ++i) {
3042 for (j = 0; j < cfg->header->num_clauses; ++j) {
3043 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3044 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3046 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3047 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3052 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3053 * it needs to continue normally, or return back to the exception handling system.
3055 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3059 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3062 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3063 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3064 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3066 if (bb->in_scount == 0) {
3069 sprintf (name, "finally_ind_bb%d", bb->block_num);
3070 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3071 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3073 ctx->bblocks [bb->block_num].finally_ind = val;
3075 /* Create a variable to hold the exception var */
3077 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3081 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3082 * LLVM bblock containing a landing pad causes problems for the
3083 * LLVM optimizer passes.
3085 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3086 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3088 ctx->builder = old_builder;
3092 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3094 MonoCompile *cfg = ctx->cfg;
3095 LLVMModuleRef lmodule = ctx->lmodule;
3096 LLVMValueRef *values = ctx->values;
3097 LLVMValueRef *addresses = ctx->addresses;
3098 MonoCallInst *call = (MonoCallInst*)ins;
3099 MonoMethodSignature *sig = call->signature;
3100 LLVMValueRef callee = NULL, lcall;
3102 LLVMCallInfo *cinfo;
3106 LLVMTypeRef llvm_sig;
3108 gboolean is_virtual, calli, preserveall;
3109 LLVMBuilderRef builder = *builder_ref;
3111 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3112 set_failure (ctx, "non-default callconv");
3116 cinfo = call->cinfo;
3118 if (call->rgctx_arg_reg)
3119 cinfo->rgctx_arg = TRUE;
3120 if (call->imt_arg_reg)
3121 cinfo->imt_arg = TRUE;
3123 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3125 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3129 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);
3130 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);
3132 preserveall = FALSE;
3134 /* FIXME: Avoid creating duplicate methods */
3136 if (ins->flags & MONO_INST_HAS_METHOD) {
3140 if (cfg->compile_aot) {
3141 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3143 set_failure (ctx, "can't encode patch");
3146 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3148 * Collect instructions representing the callee into a hash so they can be replaced
3149 * by the llvm method for the callee if the callee turns out to be direct
3150 * callable. Currently this only requires it to not fail llvm compilation.
3152 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3153 l = g_slist_prepend (l, callee);
3154 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3159 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3162 mono_create_jit_trampoline (mono_domain_get (),
3163 call->method, &error);
3164 if (!mono_error_ok (&error))
3165 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3166 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3170 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3171 /* LLVM miscompiles async methods */
3172 set_failure (ctx, "#13734");
3177 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3183 memset (&ji, 0, sizeof (ji));
3184 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3185 ji.data.target = info->name;
3187 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3189 if (cfg->compile_aot) {
3190 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3192 set_failure (ctx, "can't encode patch");
3196 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3197 target = (gpointer)mono_icall_get_wrapper (info);
3198 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3201 if (cfg->compile_aot) {
3203 if (cfg->abs_patches) {
3204 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3206 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3208 set_failure (ctx, "can't encode patch");
3214 set_failure (ctx, "aot");
3218 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3220 if (cfg->abs_patches) {
3221 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3226 * FIXME: Some trampolines might have
3227 * their own calling convention on some platforms.
3229 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3230 mono_error_assert_ok (&error);
3231 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3235 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3241 int size = sizeof (gpointer);
3244 g_assert (ins->inst_offset % size == 0);
3245 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3247 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3249 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3251 if (ins->flags & MONO_INST_HAS_METHOD) {
3256 * Collect and convert arguments
3258 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3259 len = sizeof (LLVMValueRef) * nargs;
3260 args = (LLVMValueRef*)alloca (len);
3261 memset (args, 0, len);
3262 l = call->out_ireg_args;
3264 if (call->rgctx_arg_reg) {
3265 g_assert (values [call->rgctx_arg_reg]);
3266 g_assert (cinfo->rgctx_arg_pindex < nargs);
3268 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3269 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3270 * it using a volatile load.
3273 if (!ctx->imt_rgctx_loc)
3274 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3275 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3276 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3278 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3281 if (call->imt_arg_reg) {
3282 g_assert (!ctx->llvm_only);
3283 g_assert (values [call->imt_arg_reg]);
3284 g_assert (cinfo->imt_arg_pindex < nargs);
3286 if (!ctx->imt_rgctx_loc)
3287 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3288 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3289 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3291 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3294 switch (cinfo->ret.storage) {
3295 case LLVMArgGsharedvtVariable: {
3296 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3298 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3299 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3301 g_assert (addresses [call->inst.dreg]);
3302 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3308 if (!addresses [call->inst.dreg])
3309 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3310 g_assert (cinfo->vret_arg_pindex < nargs);
3311 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3312 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3314 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3320 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3321 * use the real callee for argument type conversion.
3323 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3324 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3325 LLVMGetParamTypes (callee_type, param_types);
3327 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3330 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3332 pindex = ainfo->pindex;
3334 regpair = (guint32)(gssize)(l->data);
3335 reg = regpair & 0xffffff;
3336 args [pindex] = values [reg];
3337 switch (ainfo->storage) {
3338 case LLVMArgVtypeInReg:
3339 case LLVMArgAsFpArgs: {
3343 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3344 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3345 pindex += ainfo->ndummy_fpargs;
3347 g_assert (addresses [reg]);
3348 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3352 // FIXME: Get rid of the VMOVE
3355 case LLVMArgVtypeByVal:
3356 g_assert (addresses [reg]);
3357 args [pindex] = addresses [reg];
3359 case LLVMArgVtypeByRef: {
3360 g_assert (addresses [reg]);
3361 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3364 case LLVMArgAsIArgs:
3365 g_assert (addresses [reg]);
3366 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3368 case LLVMArgVtypeAsScalar:
3369 g_assert_not_reached ();
3371 case LLVMArgGsharedvtFixed:
3372 case LLVMArgGsharedvtFixedVtype:
3373 g_assert (addresses [reg]);
3374 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3376 case LLVMArgGsharedvtVariable:
3377 g_assert (addresses [reg]);
3378 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3381 g_assert (args [pindex]);
3382 if (i == 0 && sig->hasthis)
3383 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3385 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3388 g_assert (pindex <= nargs);
3393 // FIXME: Align call sites
3399 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3402 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3404 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3405 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3407 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3408 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3409 if (!sig->pinvoke && !cfg->llvm_only)
3410 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3412 mono_llvm_set_call_preserveall_cc (lcall);
3414 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3415 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3416 if (!ctx->llvm_only && call->rgctx_arg_reg)
3417 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3418 if (call->imt_arg_reg)
3419 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3421 /* Add byval attributes if needed */
3422 for (i = 0; i < sig->param_count; ++i) {
3423 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3425 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3426 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3430 * Convert the result
3432 switch (cinfo->ret.storage) {
3433 case LLVMArgVtypeInReg: {
3434 LLVMValueRef regs [2];
3436 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3440 if (!addresses [ins->dreg])
3441 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3443 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3444 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3445 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3446 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3449 case LLVMArgVtypeByVal:
3450 if (!addresses [call->inst.dreg])
3451 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3452 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3454 case LLVMArgFpStruct:
3455 if (!addresses [call->inst.dreg])
3456 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3457 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3459 case LLVMArgVtypeAsScalar:
3460 if (!addresses [call->inst.dreg])
3461 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3462 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3464 case LLVMArgVtypeRetAddr:
3465 case LLVMArgVtypeByRef:
3466 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3467 /* Some opcodes like STOREX_MEMBASE access these by value */
3468 g_assert (addresses [call->inst.dreg]);
3469 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3472 case LLVMArgGsharedvtVariable:
3474 case LLVMArgGsharedvtFixed:
3475 case LLVMArgGsharedvtFixedVtype:
3476 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3479 if (sig->ret->type != MONO_TYPE_VOID)
3480 /* If the method returns an unsigned value, need to zext it */
3481 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));
3485 *builder_ref = ctx->builder;
3489 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3491 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3492 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3494 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3497 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3499 if (ctx->cfg->compile_aot) {
3500 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3502 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3503 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3504 mono_memory_barrier ();
3507 ctx->module->rethrow = callee;
3509 ctx->module->throw_icall = callee;
3513 LLVMValueRef args [2];
3515 args [0] = convert (ctx, exc, exc_type);
3516 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3518 LLVMBuildUnreachable (ctx->builder);
3520 ctx->builder = create_builder (ctx);
3524 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3526 MonoMethodSignature *throw_sig;
3527 LLVMValueRef callee, arg;
3528 const char *icall_name;
3530 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3531 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3534 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3535 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3536 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3537 if (ctx->cfg->compile_aot) {
3538 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3540 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3544 * LLVM doesn't push the exception argument, so we need a different
3547 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3549 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3553 mono_memory_barrier ();
3555 ctx->module->rethrow = callee;
3557 ctx->module->throw_icall = callee;
3559 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3560 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3564 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3566 const char *icall_name = "mono_llvm_resume_exception";
3567 LLVMValueRef callee = ctx->module->resume_eh;
3569 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3572 if (ctx->cfg->compile_aot) {
3573 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3575 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3576 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3577 mono_memory_barrier ();
3579 ctx->module->resume_eh = callee;
3583 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3585 LLVMBuildUnreachable (ctx->builder);
3587 ctx->builder = create_builder (ctx);
3591 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3593 const char *icall_name = "mono_llvm_clear_exception";
3595 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3596 LLVMValueRef callee = NULL;
3599 if (ctx->cfg->compile_aot) {
3600 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3602 // FIXME: This is broken.
3603 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3607 g_assert (builder && callee);
3609 return LLVMBuildCall (builder, callee, NULL, 0, "");
3613 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3615 const char *icall_name = "mono_llvm_load_exception";
3617 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3618 LLVMValueRef callee = NULL;
3621 if (ctx->cfg->compile_aot) {
3622 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3624 // FIXME: This is broken.
3625 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3629 g_assert (builder && callee);
3631 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3636 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3638 const char *icall_name = "mono_llvm_match_exception";
3640 ctx->builder = builder;
3642 const int num_args = 5;
3643 LLVMValueRef args [num_args];
3644 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3645 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3646 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3647 if (ctx->cfg->rgctx_var) {
3648 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3649 g_assert (rgctx_alloc);
3650 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3652 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3655 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3657 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3659 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3660 LLVMValueRef callee = ctx->module->match_exc;
3663 if (ctx->cfg->compile_aot) {
3664 ctx->builder = builder;
3665 // get_callee expects ctx->builder to be the emitting builder
3666 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3668 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3669 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3670 ctx->module->match_exc = callee;
3671 mono_memory_barrier ();
3675 g_assert (builder && callee);
3677 g_assert (ctx->ex_var);
3679 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3682 // FIXME: This won't work because the code-finding makes this
3684 /*#define MONO_PERSONALITY_DEBUG*/
3686 #ifdef MONO_PERSONALITY_DEBUG
3687 static const gboolean use_debug_personality = TRUE;
3688 static const char *default_personality_name = "mono_debug_personality";
3690 static const gboolean use_debug_personality = FALSE;
3691 static const char *default_personality_name = "__gxx_personality_v0";
3695 default_cpp_lpad_exc_signature (void)
3697 static gboolean inited = FALSE;
3698 static LLVMTypeRef sig;
3701 LLVMTypeRef signature [2];
3702 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3703 signature [1] = LLVMInt32Type ();
3704 sig = LLVMStructType (signature, 2, FALSE);
3712 get_mono_personality (EmitContext *ctx)
3714 LLVMValueRef personality = NULL;
3715 static gint32 mapping_inited = FALSE;
3716 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3718 if (!use_debug_personality) {
3719 if (ctx->cfg->compile_aot) {
3720 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3721 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3722 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3723 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3726 if (ctx->cfg->compile_aot) {
3727 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3729 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3730 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3731 mono_memory_barrier ();
3735 g_assert (personality);
3739 static LLVMBasicBlockRef
3740 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3742 MonoCompile *cfg = ctx->cfg;
3743 LLVMBuilderRef old_builder = ctx->builder;
3744 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3746 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3747 ctx->builder = lpadBuilder;
3749 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3750 g_assert (handler_bb);
3752 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3753 LLVMValueRef personality = get_mono_personality (ctx);
3754 g_assert (personality);
3756 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3757 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3759 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3760 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3761 g_assert (landing_pad);
3763 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3764 LLVMAddClause (landing_pad, cast);
3766 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3767 LLVMBuilderRef resume_builder = create_builder (ctx);
3768 ctx->builder = resume_builder;
3769 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3771 emit_resume_eh (ctx, handler_bb);
3774 ctx->builder = lpadBuilder;
3775 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3777 gboolean finally_only = TRUE;
3779 MonoExceptionClause *group_cursor = group_start;
3781 for (int i = 0; i < group_size; i ++) {
3782 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3783 finally_only = FALSE;
3789 // Handle landing pad inlining
3791 if (!finally_only) {
3792 // So at each level of the exception stack we will match the exception again.
3793 // During that match, we need to compare against the handler types for the current
3794 // protected region. We send the try start and end so that we can only check against
3795 // handlers for this lexical protected region.
3796 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3798 // if returns -1, resume
3799 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3801 // else move to that target bb
3802 for (int i=0; i < group_size; i++) {
3803 MonoExceptionClause *clause = group_start + i;
3804 int clause_index = clause - cfg->header->clauses;
3805 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3806 g_assert (handler_bb);
3807 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3808 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3811 int clause_index = group_start - cfg->header->clauses;
3812 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3813 g_assert (finally_bb);
3815 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3818 ctx->builder = old_builder;
3825 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3827 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3828 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3830 // Make exception available to catch blocks
3831 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3832 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3834 g_assert (ctx->ex_var);
3835 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3837 if (bb->in_scount == 1) {
3838 MonoInst *exvar = bb->in_stack [0];
3839 g_assert (!ctx->values [exvar->dreg]);
3840 g_assert (ctx->ex_var);
3841 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3842 emit_volatile_store (ctx, exvar->dreg);
3845 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3848 LLVMBuilderRef handler_builder = create_builder (ctx);
3849 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3850 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3852 // Make the handler code end with a jump to cbb
3853 LLVMBuildBr (handler_builder, cbb);
3857 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3859 MonoCompile *cfg = ctx->cfg;
3860 LLVMValueRef *values = ctx->values;
3861 LLVMModuleRef lmodule = ctx->lmodule;
3862 BBInfo *bblocks = ctx->bblocks;
3864 LLVMValueRef personality;
3865 LLVMValueRef landing_pad;
3866 LLVMBasicBlockRef target_bb;
3868 static gint32 mapping_inited;
3869 static int ti_generator;
3872 LLVMValueRef type_info;
3876 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3878 if (cfg->compile_aot) {
3879 /* Use a dummy personality function */
3880 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3881 g_assert (personality);
3883 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3884 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3885 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3888 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3890 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3893 * Create the type info
3895 sprintf (ti_name, "type_info_%d", ti_generator);
3898 if (cfg->compile_aot) {
3899 /* decode_eh_frame () in aot-runtime.c will decode this */
3900 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3901 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3904 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3906 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3909 * After the cfg mempool is freed, the type info will point to stale memory,
3910 * but this is not a problem, since we decode it once in exception_cb during
3913 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3914 *(gint32*)ti = clause_index;
3916 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3918 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3922 LLVMTypeRef members [2], ret_type;
3924 members [0] = i8ptr;
3925 members [1] = LLVMInt32Type ();
3926 ret_type = LLVMStructType (members, 2, FALSE);
3928 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3929 LLVMAddClause (landing_pad, type_info);
3931 /* Store the exception into the exvar */
3933 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3937 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3938 * code expects control to be transferred to this landing pad even in the
3939 * presence of nested clauses. The landing pad needs to branch to the landing
3940 * pads belonging to nested clauses based on the selector value returned by
3941 * the landing pad instruction, which is passed to the landing pad in a
3942 * register by the EH code.
3944 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3945 g_assert (target_bb);
3948 * Branch to the correct landing pad
3950 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3951 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3953 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3954 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3955 MonoBasicBlock *handler_bb;
3957 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3958 g_assert (handler_bb);
3960 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3961 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3964 /* Start a new bblock which CALL_HANDLER can branch to */
3965 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3967 ctx->builder = builder = create_builder (ctx);
3968 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3970 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3972 /* Store the exception into the IL level exvar */
3973 if (bb->in_scount == 1) {
3974 g_assert (bb->in_scount == 1);
3975 exvar = bb->in_stack [0];
3977 // FIXME: This is shared with filter clauses ?
3978 g_assert (!values [exvar->dreg]);
3980 g_assert (ctx->ex_var);
3981 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3982 emit_volatile_store (ctx, exvar->dreg);
3988 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3990 MonoCompile *cfg = ctx->cfg;
3991 MonoMethodSignature *sig = ctx->sig;
3992 LLVMValueRef method = ctx->lmethod;
3993 LLVMValueRef *values = ctx->values;
3994 LLVMValueRef *addresses = ctx->addresses;
3995 LLVMCallInfo *linfo = ctx->linfo;
3996 LLVMModuleRef lmodule = ctx->lmodule;
3997 BBInfo *bblocks = ctx->bblocks;
3999 LLVMBasicBlockRef cbb;
4000 LLVMBuilderRef builder, starting_builder;
4001 gboolean has_terminator;
4003 LLVMValueRef lhs, rhs;
4006 cbb = get_end_bb (ctx, bb);
4008 builder = create_builder (ctx);
4009 ctx->builder = builder;
4010 LLVMPositionBuilderAtEnd (builder, cbb);
4015 if (bb->flags & BB_EXCEPTION_HANDLER) {
4016 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4017 set_failure (ctx, "handler without invokes");
4022 emit_llvmonly_handler_start (ctx, bb, cbb);
4024 emit_handler_start (ctx, bb, builder);
4027 builder = ctx->builder;
4030 has_terminator = FALSE;
4031 starting_builder = builder;
4032 for (ins = bb->code; ins; ins = ins->next) {
4033 const char *spec = LLVM_INS_INFO (ins->opcode);
4035 char dname_buf [128];
4037 emit_dbg_loc (ctx, builder, ins->cil_code);
4042 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4043 * Start a new bblock. If the llvm optimization passes merge these, we
4044 * can work around that by doing a volatile load + cond branch from
4045 * localloc-ed memory.
4047 //set_failure (ctx, "basic block too long");
4048 cbb = gen_bb (ctx, "CONT_LONG_BB");
4049 LLVMBuildBr (ctx->builder, cbb);
4050 ctx->builder = builder = create_builder (ctx);
4051 LLVMPositionBuilderAtEnd (builder, cbb);
4052 ctx->bblocks [bb->block_num].end_bblock = cbb;
4057 /* There could be instructions after a terminator, skip them */
4060 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4061 sprintf (dname_buf, "t%d", ins->dreg);
4065 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4066 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4068 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4069 lhs = emit_volatile_load (ctx, ins->sreg1);
4071 /* It is ok for SETRET to have an uninitialized argument */
4072 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4073 set_failure (ctx, "sreg1");
4076 lhs = values [ins->sreg1];
4082 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4083 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4084 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4085 rhs = emit_volatile_load (ctx, ins->sreg2);
4087 if (!values [ins->sreg2]) {
4088 set_failure (ctx, "sreg2");
4091 rhs = values [ins->sreg2];
4097 //mono_print_ins (ins);
4098 switch (ins->opcode) {
4101 case OP_LIVERANGE_START:
4102 case OP_LIVERANGE_END:
4105 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4108 #if SIZEOF_VOID_P == 4
4109 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4111 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4115 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4119 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4121 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4123 case OP_DUMMY_ICONST:
4124 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4126 case OP_DUMMY_I8CONST:
4127 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4129 case OP_DUMMY_R8CONST:
4130 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4133 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4134 LLVMBuildBr (builder, target_bb);
4135 has_terminator = TRUE;
4142 LLVMBasicBlockRef new_bb;
4143 LLVMBuilderRef new_builder;
4145 // The default branch is already handled
4146 // FIXME: Handle it here
4148 /* Start new bblock */
4149 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4150 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4152 lhs = convert (ctx, lhs, LLVMInt32Type ());
4153 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4154 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4155 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4157 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4160 new_builder = create_builder (ctx);
4161 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4162 LLVMBuildUnreachable (new_builder);
4164 has_terminator = TRUE;
4165 g_assert (!ins->next);
4171 switch (linfo->ret.storage) {
4172 case LLVMArgVtypeInReg: {
4173 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4174 LLVMValueRef val, addr, retval;
4177 retval = LLVMGetUndef (ret_type);
4179 if (!addresses [ins->sreg1]) {
4181 * The return type is an LLVM vector type, have to convert between it and the
4182 * real return type which is a struct type.
4184 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4185 /* Convert to 2xi64 first */
4186 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4188 for (i = 0; i < 2; ++i) {
4189 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4190 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4192 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4196 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4197 for (i = 0; i < 2; ++i) {
4198 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4199 LLVMValueRef indexes [2], part_addr;
4201 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4202 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4203 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4205 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4207 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4211 LLVMBuildRet (builder, retval);
4214 case LLVMArgVtypeAsScalar: {
4215 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4216 LLVMValueRef retval;
4218 g_assert (addresses [ins->sreg1]);
4220 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4221 LLVMBuildRet (builder, retval);
4224 case LLVMArgVtypeByVal: {
4225 LLVMValueRef retval;
4227 g_assert (addresses [ins->sreg1]);
4228 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4229 LLVMBuildRet (builder, retval);
4232 case LLVMArgVtypeByRef: {
4233 LLVMBuildRetVoid (builder);
4236 case LLVMArgGsharedvtFixed: {
4237 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4238 /* The return value is in lhs, need to store to the vret argument */
4239 /* sreg1 might not be set */
4241 g_assert (cfg->vret_addr);
4242 g_assert (values [cfg->vret_addr->dreg]);
4243 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4245 LLVMBuildRetVoid (builder);
4248 case LLVMArgGsharedvtFixedVtype: {
4250 LLVMBuildRetVoid (builder);
4253 case LLVMArgGsharedvtVariable: {
4255 LLVMBuildRetVoid (builder);
4258 case LLVMArgVtypeRetAddr: {
4259 LLVMBuildRetVoid (builder);
4262 case LLVMArgFpStruct: {
4263 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4264 LLVMValueRef retval;
4266 g_assert (addresses [ins->sreg1]);
4267 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4268 LLVMBuildRet (builder, retval);
4272 case LLVMArgNormal: {
4273 if (!lhs || ctx->is_dead [ins->sreg1]) {
4275 * The method did not set its return value, probably because it
4276 * ends with a throw.
4279 LLVMBuildRetVoid (builder);
4281 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4283 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4285 has_terminator = TRUE;
4289 g_assert_not_reached ();
4298 case OP_ICOMPARE_IMM:
4299 case OP_LCOMPARE_IMM:
4300 case OP_COMPARE_IMM: {
4302 LLVMValueRef cmp, args [16];
4303 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4305 if (ins->next->opcode == OP_NOP)
4308 if (ins->next->opcode == OP_BR)
4309 /* The comparison result is not needed */
4312 rel = mono_opcode_to_cond (ins->next->opcode);
4314 if (ins->opcode == OP_ICOMPARE_IMM) {
4315 lhs = convert (ctx, lhs, LLVMInt32Type ());
4316 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4318 if (ins->opcode == OP_LCOMPARE_IMM) {
4319 lhs = convert (ctx, lhs, LLVMInt64Type ());
4320 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4322 if (ins->opcode == OP_LCOMPARE) {
4323 lhs = convert (ctx, lhs, LLVMInt64Type ());
4324 rhs = convert (ctx, rhs, LLVMInt64Type ());
4326 if (ins->opcode == OP_ICOMPARE) {
4327 lhs = convert (ctx, lhs, LLVMInt32Type ());
4328 rhs = convert (ctx, rhs, LLVMInt32Type ());
4332 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4333 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4334 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4335 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4338 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4339 if (ins->opcode == OP_FCOMPARE) {
4340 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4341 } else if (ins->opcode == OP_RCOMPARE) {
4342 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4343 } else if (ins->opcode == OP_COMPARE_IMM) {
4344 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4345 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4347 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4348 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4349 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4350 /* The immediate is encoded in two fields */
4351 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4352 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4354 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4357 else if (ins->opcode == OP_COMPARE) {
4358 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4359 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4361 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4363 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4367 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4368 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4371 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4372 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4374 * If the target bb contains PHI instructions, LLVM requires
4375 * two PHI entries for this bblock, while we only generate one.
4376 * So convert this to an unconditional bblock. (bxc #171).
4378 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4380 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4382 has_terminator = TRUE;
4383 } else if (MONO_IS_SETCC (ins->next)) {
4384 sprintf (dname_buf, "t%d", ins->next->dreg);
4386 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4388 /* Add stores for volatile variables */
4389 emit_volatile_store (ctx, ins->next->dreg);
4390 } else if (MONO_IS_COND_EXC (ins->next)) {
4391 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4394 builder = ctx->builder;
4396 set_failure (ctx, "next");
4414 rel = mono_opcode_to_cond (ins->opcode);
4416 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4417 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4428 rel = mono_opcode_to_cond (ins->opcode);
4430 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4431 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4439 gboolean empty = TRUE;
4441 /* Check that all input bblocks really branch to us */
4442 for (i = 0; i < bb->in_count; ++i) {
4443 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4444 ins->inst_phi_args [i + 1] = -1;
4450 /* LLVM doesn't like phi instructions with zero operands */
4451 ctx->is_dead [ins->dreg] = TRUE;
4455 /* Created earlier, insert it now */
4456 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4458 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4459 int sreg1 = ins->inst_phi_args [i + 1];
4463 * Count the number of times the incoming bblock branches to us,
4464 * since llvm requires a separate entry for each.
4466 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4467 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4470 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4471 if (switch_ins->inst_many_bb [j] == bb)
4478 /* Remember for later */
4479 for (j = 0; j < count; ++j) {
4480 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4483 node->in_bb = bb->in_bb [i];
4485 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);
4495 values [ins->dreg] = lhs;
4499 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4502 values [ins->dreg] = lhs;
4504 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4506 * This is added by the spilling pass in case of the JIT,
4507 * but we have to do it ourselves.
4509 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4513 case OP_MOVE_F_TO_I4: {
4514 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4517 case OP_MOVE_I4_TO_F: {
4518 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4521 case OP_MOVE_F_TO_I8: {
4522 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4525 case OP_MOVE_I8_TO_F: {
4526 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4559 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4560 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4562 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4565 builder = ctx->builder;
4567 switch (ins->opcode) {
4570 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4574 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4578 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4582 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4586 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4590 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4594 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4598 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4602 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4606 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4610 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4614 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4618 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4622 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4626 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4629 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4632 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4636 g_assert_not_reached ();
4643 lhs = convert (ctx, lhs, LLVMFloatType ());
4644 rhs = convert (ctx, rhs, LLVMFloatType ());
4645 switch (ins->opcode) {
4647 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4650 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4653 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4656 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4659 g_assert_not_reached ();
4668 case OP_IREM_UN_IMM:
4670 case OP_IDIV_UN_IMM:
4676 case OP_ISHR_UN_IMM:
4686 case OP_LSHR_UN_IMM:
4692 case OP_SHR_UN_IMM: {
4695 if (spec [MONO_INST_SRC1] == 'l') {
4696 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4698 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4701 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4704 builder = ctx->builder;
4706 #if SIZEOF_VOID_P == 4
4707 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4708 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4711 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4712 lhs = convert (ctx, lhs, IntPtrType ());
4713 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4714 switch (ins->opcode) {
4718 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4722 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4727 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4731 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4733 case OP_IDIV_UN_IMM:
4734 case OP_LDIV_UN_IMM:
4735 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4739 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4741 case OP_IREM_UN_IMM:
4742 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4747 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4751 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4755 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4760 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4765 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4767 case OP_ISHR_UN_IMM:
4768 /* This is used to implement conv.u4, so the lhs could be an i8 */
4769 lhs = convert (ctx, lhs, LLVMInt32Type ());
4770 imm = convert (ctx, imm, LLVMInt32Type ());
4771 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4773 case OP_LSHR_UN_IMM:
4775 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4778 g_assert_not_reached ();
4783 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4786 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4789 lhs = convert (ctx, lhs, LLVMDoubleType ());
4790 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4793 lhs = convert (ctx, lhs, LLVMFloatType ());
4794 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4797 guint32 v = 0xffffffff;
4798 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4802 guint64 v = 0xffffffffffffffffLL;
4803 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4806 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4808 LLVMValueRef v1, v2;
4810 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4811 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4812 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4817 case OP_ICONV_TO_I1:
4818 case OP_ICONV_TO_I2:
4819 case OP_ICONV_TO_I4:
4820 case OP_ICONV_TO_U1:
4821 case OP_ICONV_TO_U2:
4822 case OP_ICONV_TO_U4:
4823 case OP_LCONV_TO_I1:
4824 case OP_LCONV_TO_I2:
4825 case OP_LCONV_TO_U1:
4826 case OP_LCONV_TO_U2:
4827 case OP_LCONV_TO_U4: {
4830 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);
4832 /* Have to do two casts since our vregs have type int */
4833 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4835 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4837 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4840 case OP_ICONV_TO_I8:
4841 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4843 case OP_ICONV_TO_U8:
4844 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4846 case OP_FCONV_TO_I4:
4847 case OP_RCONV_TO_I4:
4848 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4850 case OP_FCONV_TO_I1:
4851 case OP_RCONV_TO_I1:
4852 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4854 case OP_FCONV_TO_U1:
4855 case OP_RCONV_TO_U1:
4856 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4858 case OP_FCONV_TO_I2:
4859 case OP_RCONV_TO_I2:
4860 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4862 case OP_FCONV_TO_U2:
4863 case OP_RCONV_TO_U2:
4864 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4866 case OP_RCONV_TO_U4:
4867 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4869 case OP_FCONV_TO_I8:
4870 case OP_RCONV_TO_I8:
4871 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4874 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4876 case OP_ICONV_TO_R8:
4877 case OP_LCONV_TO_R8:
4878 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4880 case OP_ICONV_TO_R_UN:
4881 case OP_LCONV_TO_R_UN:
4882 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4884 #if SIZEOF_VOID_P == 4
4887 case OP_LCONV_TO_I4:
4888 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4890 case OP_ICONV_TO_R4:
4891 case OP_LCONV_TO_R4:
4892 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4894 values [ins->dreg] = v;
4896 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4898 case OP_FCONV_TO_R4:
4899 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4901 values [ins->dreg] = v;
4903 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4905 case OP_RCONV_TO_R8:
4906 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4908 case OP_RCONV_TO_R4:
4909 values [ins->dreg] = lhs;
4912 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4915 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4918 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4920 case OP_LOCALLOC_IMM: {
4923 guint32 size = ins->inst_imm;
4924 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4926 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4928 if (ins->flags & MONO_INST_INIT) {
4929 LLVMValueRef args [5];
4932 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4933 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4934 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4935 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4936 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4939 values [ins->dreg] = v;
4943 LLVMValueRef v, size;
4945 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), "");
4947 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4949 if (ins->flags & MONO_INST_INIT) {
4950 LLVMValueRef args [5];
4953 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4955 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4956 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4957 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4959 values [ins->dreg] = v;
4963 case OP_LOADI1_MEMBASE:
4964 case OP_LOADU1_MEMBASE:
4965 case OP_LOADI2_MEMBASE:
4966 case OP_LOADU2_MEMBASE:
4967 case OP_LOADI4_MEMBASE:
4968 case OP_LOADU4_MEMBASE:
4969 case OP_LOADI8_MEMBASE:
4970 case OP_LOADR4_MEMBASE:
4971 case OP_LOADR8_MEMBASE:
4972 case OP_LOAD_MEMBASE:
4980 LLVMValueRef base, index, addr;
4982 gboolean sext = FALSE, zext = FALSE;
4983 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4985 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4990 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)) {
4991 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4996 if (ins->inst_offset == 0) {
4998 } else if (ins->inst_offset % size != 0) {
4999 /* Unaligned load */
5000 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5001 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5003 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5004 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5008 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5010 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5012 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5014 * These will signal LLVM that these loads do not alias any stores, and
5015 * they can't fail, allowing them to be hoisted out of loops.
5017 set_invariant_load_flag (values [ins->dreg]);
5018 #if LLVM_API_VERSION < 100
5019 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5024 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5026 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5027 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5028 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5032 case OP_STOREI1_MEMBASE_REG:
5033 case OP_STOREI2_MEMBASE_REG:
5034 case OP_STOREI4_MEMBASE_REG:
5035 case OP_STOREI8_MEMBASE_REG:
5036 case OP_STORER4_MEMBASE_REG:
5037 case OP_STORER8_MEMBASE_REG:
5038 case OP_STORE_MEMBASE_REG: {
5040 LLVMValueRef index, addr;
5042 gboolean sext = FALSE, zext = FALSE;
5043 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5045 if (!values [ins->inst_destbasereg]) {
5046 set_failure (ctx, "inst_destbasereg");
5050 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5052 if (ins->inst_offset % size != 0) {
5053 /* Unaligned store */
5054 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5055 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5057 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5058 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5060 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5064 case OP_STOREI1_MEMBASE_IMM:
5065 case OP_STOREI2_MEMBASE_IMM:
5066 case OP_STOREI4_MEMBASE_IMM:
5067 case OP_STOREI8_MEMBASE_IMM:
5068 case OP_STORE_MEMBASE_IMM: {
5070 LLVMValueRef index, addr;
5072 gboolean sext = FALSE, zext = FALSE;
5073 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5075 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5077 if (ins->inst_offset % size != 0) {
5078 /* Unaligned store */
5079 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5080 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5082 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5083 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5085 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5090 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5092 case OP_OUTARG_VTRETADDR:
5100 case OP_VOIDCALL_MEMBASE:
5101 case OP_CALL_MEMBASE:
5102 case OP_LCALL_MEMBASE:
5103 case OP_FCALL_MEMBASE:
5104 case OP_RCALL_MEMBASE:
5105 case OP_VCALL_MEMBASE:
5106 case OP_VOIDCALL_REG:
5111 case OP_VCALL_REG: {
5112 process_call (ctx, bb, &builder, ins);
5117 LLVMValueRef indexes [2];
5118 MonoJumpInfo *tmp_ji, *ji;
5119 LLVMValueRef got_entry_addr;
5123 * FIXME: Can't allocate from the cfg mempool since that is freed if
5124 * the LLVM compile fails.
5126 tmp_ji = g_new0 (MonoJumpInfo, 1);
5127 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5128 tmp_ji->data.target = ins->inst_p0;
5130 ji = mono_aot_patch_info_dup (tmp_ji);
5133 ji->next = cfg->patch_info;
5134 cfg->patch_info = ji;
5136 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5137 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5138 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5139 if (!mono_aot_is_shared_got_offset (got_offset)) {
5140 //mono_print_ji (ji);
5142 ctx->has_got_access = TRUE;
5145 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5146 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5147 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5149 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5150 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5152 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5153 if (!cfg->llvm_only)
5154 set_invariant_load_flag (values [ins->dreg]);
5157 case OP_NOT_REACHED:
5158 LLVMBuildUnreachable (builder);
5159 has_terminator = TRUE;
5160 g_assert (bb->block_num < cfg->max_block_num);
5161 ctx->unreachable [bb->block_num] = TRUE;
5162 /* Might have instructions after this */
5164 MonoInst *next = ins->next;
5166 * FIXME: If later code uses the regs defined by these instructions,
5167 * compilation will fail.
5169 MONO_DELETE_INS (bb, next);
5173 MonoInst *var = ins->inst_i0;
5175 if (var->opcode == OP_VTARG_ADDR) {
5176 /* The variable contains the vtype address */
5177 values [ins->dreg] = values [var->dreg];
5178 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5179 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5181 values [ins->dreg] = addresses [var->dreg];
5186 LLVMValueRef args [1];
5188 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5189 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5193 LLVMValueRef args [1];
5195 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5196 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5200 LLVMValueRef args [1];
5202 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5203 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5207 LLVMValueRef args [1];
5209 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5210 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5224 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5225 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5227 switch (ins->opcode) {
5230 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5234 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5238 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5242 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5245 g_assert_not_reached ();
5248 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5251 case OP_ATOMIC_EXCHANGE_I4:
5252 case OP_ATOMIC_EXCHANGE_I8: {
5253 LLVMValueRef args [2];
5256 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5257 t = LLVMInt32Type ();
5259 t = LLVMInt64Type ();
5261 g_assert (ins->inst_offset == 0);
5263 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5264 args [1] = convert (ctx, rhs, t);
5266 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5269 case OP_ATOMIC_ADD_I4:
5270 case OP_ATOMIC_ADD_I8: {
5271 LLVMValueRef args [2];
5274 if (ins->opcode == OP_ATOMIC_ADD_I4)
5275 t = LLVMInt32Type ();
5277 t = LLVMInt64Type ();
5279 g_assert (ins->inst_offset == 0);
5281 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5282 args [1] = convert (ctx, rhs, t);
5283 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5286 case OP_ATOMIC_CAS_I4:
5287 case OP_ATOMIC_CAS_I8: {
5288 LLVMValueRef args [3], val;
5291 if (ins->opcode == OP_ATOMIC_CAS_I4)
5292 t = LLVMInt32Type ();
5294 t = LLVMInt64Type ();
5296 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5298 args [1] = convert (ctx, values [ins->sreg3], t);
5300 args [2] = convert (ctx, values [ins->sreg2], t);
5301 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5302 /* cmpxchg returns a pair */
5303 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5306 case OP_MEMORY_BARRIER: {
5307 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5310 case OP_ATOMIC_LOAD_I1:
5311 case OP_ATOMIC_LOAD_I2:
5312 case OP_ATOMIC_LOAD_I4:
5313 case OP_ATOMIC_LOAD_I8:
5314 case OP_ATOMIC_LOAD_U1:
5315 case OP_ATOMIC_LOAD_U2:
5316 case OP_ATOMIC_LOAD_U4:
5317 case OP_ATOMIC_LOAD_U8:
5318 case OP_ATOMIC_LOAD_R4:
5319 case OP_ATOMIC_LOAD_R8: {
5320 set_failure (ctx, "atomic mono.load intrinsic");
5324 gboolean sext, zext;
5326 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5327 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5328 LLVMValueRef index, addr;
5330 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5335 if (ins->inst_offset != 0) {
5336 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5337 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5342 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5344 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5347 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5349 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5353 case OP_ATOMIC_STORE_I1:
5354 case OP_ATOMIC_STORE_I2:
5355 case OP_ATOMIC_STORE_I4:
5356 case OP_ATOMIC_STORE_I8:
5357 case OP_ATOMIC_STORE_U1:
5358 case OP_ATOMIC_STORE_U2:
5359 case OP_ATOMIC_STORE_U4:
5360 case OP_ATOMIC_STORE_U8:
5361 case OP_ATOMIC_STORE_R4:
5362 case OP_ATOMIC_STORE_R8: {
5363 set_failure (ctx, "atomic mono.store intrinsic");
5367 gboolean sext, zext;
5369 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5370 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5371 LLVMValueRef index, addr, value;
5373 if (!values [ins->inst_destbasereg]) {
5374 set_failure (ctx, "inst_destbasereg");
5378 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5380 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5381 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5382 value = convert (ctx, values [ins->sreg1], t);
5384 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5388 case OP_RELAXED_NOP: {
5389 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5390 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5397 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5399 // 257 == FS segment register
5400 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5402 // 256 == GS segment register
5403 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5406 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5407 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5408 /* See mono_amd64_emit_tls_get () */
5409 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5411 // 256 == GS segment register
5412 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5413 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5415 set_failure (ctx, "opcode tls-get");
5421 case OP_TLS_GET_REG: {
5422 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5423 /* See emit_tls_get_reg () */
5424 // 256 == GS segment register
5425 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5426 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5428 set_failure (ctx, "opcode tls-get");
5434 case OP_TLS_SET_REG: {
5435 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5436 /* See emit_tls_get_reg () */
5437 // 256 == GS segment register
5438 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5439 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5441 set_failure (ctx, "opcode tls-set-reg");
5451 case OP_IADD_OVF_UN:
5453 case OP_ISUB_OVF_UN:
5455 case OP_IMUL_OVF_UN:
5456 #if SIZEOF_VOID_P == 8
5458 case OP_LADD_OVF_UN:
5460 case OP_LSUB_OVF_UN:
5462 case OP_LMUL_OVF_UN:
5465 LLVMValueRef args [2], val, ovf, func;
5467 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5468 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5469 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5471 val = LLVMBuildCall (builder, func, args, 2, "");
5472 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5473 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5474 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5477 builder = ctx->builder;
5483 * We currently model them using arrays. Promotion to local vregs is
5484 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5485 * so we always have an entry in cfg->varinfo for them.
5486 * FIXME: Is this needed ?
5489 MonoClass *klass = ins->klass;
5490 LLVMValueRef args [5];
5494 set_failure (ctx, "!klass");
5498 if (!addresses [ins->dreg])
5499 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5500 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5501 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5502 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5504 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5505 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5506 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5509 case OP_DUMMY_VZERO:
5512 case OP_STOREV_MEMBASE:
5513 case OP_LOADV_MEMBASE:
5515 MonoClass *klass = ins->klass;
5516 LLVMValueRef src = NULL, dst, args [5];
5517 gboolean done = FALSE;
5521 set_failure (ctx, "!klass");
5525 if (mini_is_gsharedvt_klass (klass)) {
5527 set_failure (ctx, "gsharedvt");
5531 switch (ins->opcode) {
5532 case OP_STOREV_MEMBASE:
5533 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5534 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5535 /* Decomposed earlier */
5536 g_assert_not_reached ();
5539 if (!addresses [ins->sreg1]) {
5541 g_assert (values [ins->sreg1]);
5542 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));
5543 LLVMBuildStore (builder, values [ins->sreg1], dst);
5546 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5547 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5550 case OP_LOADV_MEMBASE:
5551 if (!addresses [ins->dreg])
5552 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5553 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5554 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5557 if (!addresses [ins->sreg1])
5558 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5559 if (!addresses [ins->dreg])
5560 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5561 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5562 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5565 g_assert_not_reached ();
5575 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5576 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5578 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5579 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5580 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5583 case OP_LLVM_OUTARG_VT: {
5584 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5585 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5587 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5588 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5590 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5591 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5593 g_assert (addresses [ins->sreg1]);
5594 addresses [ins->dreg] = addresses [ins->sreg1];
5596 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5597 if (!addresses [ins->sreg1]) {
5598 addresses [ins->sreg1] = build_alloca (ctx, t);
5599 g_assert (values [ins->sreg1]);
5601 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5602 addresses [ins->dreg] = addresses [ins->sreg1];
5604 if (!addresses [ins->sreg1]) {
5605 addresses [ins->sreg1] = build_alloca (ctx, t);
5606 g_assert (values [ins->sreg1]);
5607 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5609 addresses [ins->dreg] = addresses [ins->sreg1];
5617 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5619 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5622 case OP_LOADX_MEMBASE: {
5623 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5626 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5627 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5630 case OP_STOREX_MEMBASE: {
5631 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5634 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5635 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5642 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5646 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5652 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5656 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5660 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5664 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5667 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5670 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5673 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5677 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5688 LLVMValueRef v = NULL;
5690 switch (ins->opcode) {
5695 t = LLVMVectorType (LLVMInt32Type (), 4);
5696 rt = LLVMVectorType (LLVMFloatType (), 4);
5702 t = LLVMVectorType (LLVMInt64Type (), 2);
5703 rt = LLVMVectorType (LLVMDoubleType (), 2);
5706 t = LLVMInt32Type ();
5707 rt = LLVMInt32Type ();
5708 g_assert_not_reached ();
5711 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5712 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5713 switch (ins->opcode) {
5716 v = LLVMBuildAnd (builder, lhs, rhs, "");
5720 v = LLVMBuildOr (builder, lhs, rhs, "");
5724 v = LLVMBuildXor (builder, lhs, rhs, "");
5728 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5731 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5755 case OP_PADDB_SAT_UN:
5756 case OP_PADDW_SAT_UN:
5757 case OP_PSUBB_SAT_UN:
5758 case OP_PSUBW_SAT_UN:
5766 case OP_PMULW_HIGH_UN: {
5767 LLVMValueRef args [2];
5772 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5779 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5783 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5791 case OP_EXTRACTX_U2:
5793 case OP_EXTRACT_U1: {
5795 gboolean zext = FALSE;
5797 t = simd_op_to_llvm_type (ins->opcode);
5799 switch (ins->opcode) {
5807 case OP_EXTRACTX_U2:
5812 t = LLVMInt32Type ();
5813 g_assert_not_reached ();
5816 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5817 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5819 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5828 case OP_EXPAND_R8: {
5829 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5830 LLVMValueRef mask [16], v;
5833 for (i = 0; i < 16; ++i)
5834 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5836 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5838 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5839 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5844 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5847 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5850 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5853 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5856 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5859 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5870 case OP_EXTRACT_MASK:
5877 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5879 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5885 LLVMValueRef args [3];
5889 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5891 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5896 /* This is only used for implementing shifts by non-immediate */
5897 values [ins->dreg] = lhs;
5908 LLVMValueRef args [3];
5911 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5913 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5924 case OP_PSHLQ_REG: {
5925 LLVMValueRef args [3];
5928 args [1] = values [ins->sreg2];
5930 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5937 case OP_PSHUFLEW_LOW:
5938 case OP_PSHUFLEW_HIGH: {
5940 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5941 int i, mask_size = 0;
5942 int imask = ins->inst_c0;
5944 /* Convert the x86 shuffle mask to LLVM's */
5945 switch (ins->opcode) {
5948 mask [0] = ((imask >> 0) & 3);
5949 mask [1] = ((imask >> 2) & 3);
5950 mask [2] = ((imask >> 4) & 3) + 4;
5951 mask [3] = ((imask >> 6) & 3) + 4;
5952 v1 = values [ins->sreg1];
5953 v2 = values [ins->sreg2];
5957 mask [0] = ((imask >> 0) & 1);
5958 mask [1] = ((imask >> 1) & 1) + 2;
5959 v1 = values [ins->sreg1];
5960 v2 = values [ins->sreg2];
5962 case OP_PSHUFLEW_LOW:
5964 mask [0] = ((imask >> 0) & 3);
5965 mask [1] = ((imask >> 2) & 3);
5966 mask [2] = ((imask >> 4) & 3);
5967 mask [3] = ((imask >> 6) & 3);
5972 v1 = values [ins->sreg1];
5973 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5975 case OP_PSHUFLEW_HIGH:
5981 mask [4] = 4 + ((imask >> 0) & 3);
5982 mask [5] = 4 + ((imask >> 2) & 3);
5983 mask [6] = 4 + ((imask >> 4) & 3);
5984 mask [7] = 4 + ((imask >> 6) & 3);
5985 v1 = values [ins->sreg1];
5986 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5990 mask [0] = ((imask >> 0) & 3);
5991 mask [1] = ((imask >> 2) & 3);
5992 mask [2] = ((imask >> 4) & 3);
5993 mask [3] = ((imask >> 6) & 3);
5994 v1 = values [ins->sreg1];
5995 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5998 g_assert_not_reached ();
6000 for (i = 0; i < mask_size; ++i)
6001 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6003 values [ins->dreg] =
6004 LLVMBuildShuffleVector (builder, v1, v2,
6005 LLVMConstVector (mask_values, mask_size), dname);
6009 case OP_UNPACK_LOWB:
6010 case OP_UNPACK_LOWW:
6011 case OP_UNPACK_LOWD:
6012 case OP_UNPACK_LOWQ:
6013 case OP_UNPACK_LOWPS:
6014 case OP_UNPACK_LOWPD:
6015 case OP_UNPACK_HIGHB:
6016 case OP_UNPACK_HIGHW:
6017 case OP_UNPACK_HIGHD:
6018 case OP_UNPACK_HIGHQ:
6019 case OP_UNPACK_HIGHPS:
6020 case OP_UNPACK_HIGHPD: {
6022 LLVMValueRef mask_values [16];
6023 int i, mask_size = 0;
6024 gboolean low = FALSE;
6026 switch (ins->opcode) {
6027 case OP_UNPACK_LOWB:
6031 case OP_UNPACK_LOWW:
6035 case OP_UNPACK_LOWD:
6036 case OP_UNPACK_LOWPS:
6040 case OP_UNPACK_LOWQ:
6041 case OP_UNPACK_LOWPD:
6045 case OP_UNPACK_HIGHB:
6048 case OP_UNPACK_HIGHW:
6051 case OP_UNPACK_HIGHD:
6052 case OP_UNPACK_HIGHPS:
6055 case OP_UNPACK_HIGHQ:
6056 case OP_UNPACK_HIGHPD:
6060 g_assert_not_reached ();
6064 for (i = 0; i < (mask_size / 2); ++i) {
6066 mask [(i * 2) + 1] = mask_size + i;
6069 for (i = 0; i < (mask_size / 2); ++i) {
6070 mask [(i * 2)] = (mask_size / 2) + i;
6071 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6075 for (i = 0; i < mask_size; ++i)
6076 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6078 values [ins->dreg] =
6079 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6080 LLVMConstVector (mask_values, mask_size), dname);
6085 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6086 LLVMValueRef v, val;
6088 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6089 val = LLVMConstNull (t);
6090 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6091 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6093 values [ins->dreg] = val;
6097 case OP_DUPPS_HIGH: {
6098 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6099 LLVMValueRef v1, v2, val;
6102 if (ins->opcode == OP_DUPPS_LOW) {
6103 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6104 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6106 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6107 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6109 val = LLVMConstNull (t);
6110 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6111 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6112 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6113 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6115 values [ins->dreg] = val;
6125 * EXCEPTION HANDLING
6127 case OP_IMPLICIT_EXCEPTION:
6128 /* This marks a place where an implicit exception can happen */
6129 if (bb->region != -1)
6130 set_failure (ctx, "implicit-exception");
6134 gboolean rethrow = (ins->opcode == OP_RETHROW);
6135 if (ctx->llvm_only) {
6136 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6137 has_terminator = TRUE;
6138 ctx->unreachable [bb->block_num] = TRUE;
6140 emit_throw (ctx, bb, rethrow, lhs);
6141 builder = ctx->builder;
6145 case OP_CALL_HANDLER: {
6147 * We don't 'call' handlers, but instead simply branch to them.
6148 * The code generated by ENDFINALLY will branch back to us.
6150 LLVMBasicBlockRef noex_bb;
6152 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6154 bb_list = info->call_handler_return_bbs;
6157 * Set the indicator variable for the finally clause.
6159 lhs = info->finally_ind;
6161 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6163 /* Branch to the finally clause */
6164 LLVMBuildBr (builder, info->call_handler_target_bb);
6166 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6167 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6169 builder = ctx->builder = create_builder (ctx);
6170 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6172 bblocks [bb->block_num].end_bblock = noex_bb;
6175 case OP_START_HANDLER: {
6178 case OP_ENDFINALLY: {
6179 LLVMBasicBlockRef resume_bb;
6180 MonoBasicBlock *handler_bb;
6181 LLVMValueRef val, switch_ins, callee;
6185 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6186 g_assert (handler_bb);
6187 info = &bblocks [handler_bb->block_num];
6188 lhs = info->finally_ind;
6191 bb_list = info->call_handler_return_bbs;
6193 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6195 /* Load the finally variable */
6196 val = LLVMBuildLoad (builder, lhs, "");
6198 /* Reset the variable */
6199 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6201 /* Branch to either resume_bb, or to the bblocks in bb_list */
6202 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6204 * The other targets are added at the end to handle OP_CALL_HANDLER
6205 * opcodes processed later.
6207 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6209 builder = ctx->builder = create_builder (ctx);
6210 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6212 if (ctx->llvm_only) {
6213 emit_resume_eh (ctx, bb);
6215 if (ctx->cfg->compile_aot) {
6216 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6218 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6220 LLVMBuildCall (builder, callee, NULL, 0, "");
6221 LLVMBuildUnreachable (builder);
6224 has_terminator = TRUE;
6227 case OP_IL_SEQ_POINT:
6232 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6233 set_failure (ctx, reason);
6241 /* Convert the value to the type required by phi nodes */
6242 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6243 if (!values [ins->dreg])
6245 values [ins->dreg] = addresses [ins->dreg];
6247 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6250 /* Add stores for volatile variables */
6251 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6252 emit_volatile_store (ctx, ins->dreg);
6258 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6259 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6262 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6263 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6264 LLVMBuildRetVoid (builder);
6267 if (bb == cfg->bb_entry)
6268 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6272 * mono_llvm_check_method_supported:
6274 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6275 * compiling a method twice.
6278 mono_llvm_check_method_supported (MonoCompile *cfg)
6285 if (cfg->method->save_lmf) {
6286 cfg->exception_message = g_strdup ("lmf");
6287 cfg->disable_llvm = TRUE;
6289 if (cfg->disable_llvm)
6293 * Nested clauses where one of the clauses is a finally clause is
6294 * not supported, because LLVM can't figure out the control flow,
6295 * probably because we resume exception handling by calling our
6296 * own function instead of using the 'resume' llvm instruction.
6298 for (i = 0; i < cfg->header->num_clauses; ++i) {
6299 for (j = 0; j < cfg->header->num_clauses; ++j) {
6300 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6301 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6303 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6304 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6305 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6306 cfg->exception_message = g_strdup ("nested clauses");
6307 cfg->disable_llvm = TRUE;
6312 if (cfg->disable_llvm)
6316 if (cfg->method->dynamic) {
6317 cfg->exception_message = g_strdup ("dynamic.");
6318 cfg->disable_llvm = TRUE;
6320 if (cfg->disable_llvm)
6324 static LLVMCallInfo*
6325 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6327 LLVMCallInfo *linfo;
6330 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6334 * Gsharedvt methods have the following calling convention:
6335 * - all arguments are passed by ref, even non generic ones
6336 * - the return value is returned by ref too, using a vret
6337 * argument passed after 'this'.
6339 n = sig->param_count + sig->hasthis;
6340 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6344 linfo->args [pindex ++].storage = LLVMArgNormal;
6346 if (sig->ret->type != MONO_TYPE_VOID) {
6347 if (mini_is_gsharedvt_variable_type (sig->ret))
6348 linfo->ret.storage = LLVMArgGsharedvtVariable;
6349 else if (mini_type_is_vtype (sig->ret))
6350 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6352 linfo->ret.storage = LLVMArgGsharedvtFixed;
6353 linfo->vret_arg_index = pindex;
6355 linfo->ret.storage = LLVMArgNone;
6358 for (i = 0; i < sig->param_count; ++i) {
6359 if (sig->params [i]->byref)
6360 linfo->args [pindex].storage = LLVMArgNormal;
6361 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6362 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6363 else if (mini_type_is_vtype (sig->params [i]))
6364 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6366 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6367 linfo->args [pindex].type = sig->params [i];
6374 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6375 for (i = 0; i < sig->param_count; ++i)
6376 linfo->args [i + sig->hasthis].type = sig->params [i];
6382 emit_method_inner (EmitContext *ctx);
6385 free_ctx (EmitContext *ctx)
6389 g_free (ctx->values);
6390 g_free (ctx->addresses);
6391 g_free (ctx->vreg_types);
6392 g_free (ctx->vreg_cli_types);
6393 g_free (ctx->is_dead);
6394 g_free (ctx->unreachable);
6395 g_ptr_array_free (ctx->phi_values, TRUE);
6396 g_free (ctx->bblocks);
6397 g_hash_table_destroy (ctx->region_to_handler);
6398 g_hash_table_destroy (ctx->clause_to_handler);
6399 g_free (ctx->method_name);
6400 g_ptr_array_free (ctx->bblock_list, TRUE);
6402 for (l = ctx->builders; l; l = l->next) {
6403 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6404 LLVMDisposeBuilder (builder);
6411 * mono_llvm_emit_method:
6413 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6416 mono_llvm_emit_method (MonoCompile *cfg)
6420 gboolean is_linkonce = FALSE;
6423 /* The code below might acquire the loader lock, so use it for global locking */
6424 mono_loader_lock ();
6426 /* Used to communicate with the callbacks */
6427 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6429 ctx = g_new0 (EmitContext, 1);
6431 ctx->mempool = cfg->mempool;
6434 * This maps vregs to the LLVM instruction defining them
6436 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6438 * This maps vregs for volatile variables to the LLVM instruction defining their
6441 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6442 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6443 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6444 ctx->phi_values = g_ptr_array_sized_new (256);
6446 * This signals whenever the vreg was defined by a phi node with no input vars
6447 * (i.e. all its input bblocks end with NOT_REACHABLE).
6449 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6450 /* Whenever the bblock is unreachable */
6451 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6452 ctx->bblock_list = g_ptr_array_sized_new (256);
6454 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6455 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6456 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6457 if (cfg->compile_aot) {
6458 ctx->module = &aot_module;
6462 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6463 * linkage for them. This requires the following:
6464 * - the method needs to have a unique mangled name
6465 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6467 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6469 method_name = mono_aot_get_mangled_method_name (cfg->method);
6471 is_linkonce = FALSE;
6474 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6476 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6480 method_name = mono_aot_get_method_name (cfg);
6481 cfg->llvm_method_name = g_strdup (method_name);
6483 init_jit_module (cfg->domain);
6484 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6485 method_name = mono_method_full_name (cfg->method, TRUE);
6487 ctx->method_name = method_name;
6488 ctx->is_linkonce = is_linkonce;
6490 ctx->lmodule = ctx->module->lmodule;
6491 ctx->llvm_only = ctx->module->llvm_only;
6493 emit_method_inner (ctx);
6495 if (!ctx_ok (ctx)) {
6497 /* Need to add unused phi nodes as they can be referenced by other values */
6498 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6499 LLVMBuilderRef builder;
6501 builder = create_builder (ctx);
6502 LLVMPositionBuilderAtEnd (builder, phi_bb);
6504 for (i = 0; i < ctx->phi_values->len; ++i) {
6505 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6506 if (LLVMGetInstructionParent (v) == NULL)
6507 LLVMInsertIntoBuilder (builder, v);
6510 LLVMDeleteFunction (ctx->lmethod);
6516 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6518 mono_loader_unlock ();
6522 emit_method_inner (EmitContext *ctx)
6524 MonoCompile *cfg = ctx->cfg;
6525 MonoMethodSignature *sig;
6527 LLVMTypeRef method_type;
6528 LLVMValueRef method = NULL;
6529 LLVMValueRef *values = ctx->values;
6530 int i, max_block_num, bb_index;
6531 gboolean last = FALSE;
6532 LLVMCallInfo *linfo;
6533 LLVMModuleRef lmodule = ctx->lmodule;
6535 GPtrArray *bblock_list = ctx->bblock_list;
6536 MonoMethodHeader *header;
6537 MonoExceptionClause *clause;
6540 if (cfg->gsharedvt && !cfg->llvm_only) {
6541 set_failure (ctx, "gsharedvt");
6547 static int count = 0;
6550 if (g_getenv ("LLVM_COUNT")) {
6551 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6552 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6556 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6557 set_failure (ctx, "count");
6564 sig = mono_method_signature (cfg->method);
6567 linfo = get_llvm_call_info (cfg, sig);
6573 linfo->rgctx_arg = TRUE;
6574 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6578 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6579 ctx->lmethod = method;
6581 if (!cfg->llvm_only)
6582 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6583 LLVMSetLinkage (method, LLVMPrivateLinkage);
6585 LLVMAddFunctionAttr (method, LLVMUWTable);
6587 if (cfg->compile_aot) {
6588 LLVMSetLinkage (method, LLVMInternalLinkage);
6589 if (ctx->module->external_symbols) {
6590 LLVMSetLinkage (method, LLVMExternalLinkage);
6591 LLVMSetVisibility (method, LLVMHiddenVisibility);
6593 if (ctx->is_linkonce) {
6594 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6595 LLVMSetVisibility (method, LLVMDefaultVisibility);
6598 LLVMSetLinkage (method, LLVMPrivateLinkage);
6601 if (cfg->method->save_lmf && !cfg->llvm_only) {
6602 set_failure (ctx, "lmf");
6606 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6607 set_failure (ctx, "pinvoke signature");
6611 header = cfg->header;
6612 for (i = 0; i < header->num_clauses; ++i) {
6613 clause = &header->clauses [i];
6614 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6615 set_failure (ctx, "non-finally/catch clause.");
6619 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6620 /* We can't handle inlined methods with clauses */
6621 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6623 if (linfo->rgctx_arg) {
6624 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6625 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6627 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6628 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6629 * CC_X86_64_Mono in X86CallingConv.td.
6631 if (!ctx->llvm_only)
6632 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6633 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6635 ctx->rgctx_arg_pindex = -1;
6637 if (cfg->vret_addr) {
6638 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6639 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6640 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6641 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6642 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6647 ctx->this_arg_pindex = linfo->this_arg_pindex;
6648 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6649 values [cfg->args [0]->dreg] = ctx->this_arg;
6650 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6653 names = g_new (char *, sig->param_count);
6654 mono_method_get_param_names (cfg->method, (const char **) names);
6656 for (i = 0; i < sig->param_count; ++i) {
6657 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6659 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6662 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6663 name = g_strdup_printf ("dummy_%d_%d", i, j);
6664 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6668 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6669 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6670 if (names [i] && names [i][0] != '\0')
6671 name = g_strdup_printf ("p_arg_%s", names [i]);
6673 name = g_strdup_printf ("p_arg_%d", i);
6675 if (names [i] && names [i][0] != '\0')
6676 name = g_strdup_printf ("arg_%s", names [i]);
6678 name = g_strdup_printf ("arg_%d", i);
6680 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6682 if (ainfo->storage == LLVMArgVtypeByVal)
6683 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6685 if (ainfo->storage == LLVMArgVtypeByRef) {
6687 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6692 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6693 ctx->minfo = mono_debug_lookup_method (cfg->method);
6694 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6698 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6699 max_block_num = MAX (max_block_num, bb->block_num);
6700 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6702 /* Add branches between non-consecutive bblocks */
6703 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6704 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6705 bb->next_bb != bb->last_ins->inst_false_bb) {
6707 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6708 inst->opcode = OP_BR;
6709 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6710 mono_bblock_add_inst (bb, inst);
6715 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6716 * was later optimized away, so clear these flags, and add them back for the still
6717 * present OP_LDADDR instructions.
6719 for (i = 0; i < cfg->next_vreg; ++i) {
6722 ins = get_vreg_to_inst (cfg, i);
6723 if (ins && ins != cfg->rgctx_var)
6724 ins->flags &= ~MONO_INST_INDIRECT;
6728 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6730 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6732 LLVMBuilderRef builder;
6734 char dname_buf[128];
6736 builder = create_builder (ctx);
6738 for (ins = bb->code; ins; ins = ins->next) {
6739 switch (ins->opcode) {
6744 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6749 if (ins->opcode == OP_VPHI) {
6750 /* Treat valuetype PHI nodes as operating on the address itself */
6751 g_assert (ins->klass);
6752 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6756 * Have to precreate these, as they can be referenced by
6757 * earlier instructions.
6759 sprintf (dname_buf, "t%d", ins->dreg);
6761 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6763 if (ins->opcode == OP_VPHI)
6764 ctx->addresses [ins->dreg] = values [ins->dreg];
6766 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6769 * Set the expected type of the incoming arguments since these have
6770 * to have the same type.
6772 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6773 int sreg1 = ins->inst_phi_args [i + 1];
6776 ctx->vreg_types [sreg1] = phi_type;
6781 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6790 * Create an ordering for bblocks, use the depth first order first, then
6791 * put the exception handling bblocks last.
6793 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6794 bb = cfg->bblocks [bb_index];
6795 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6796 g_ptr_array_add (bblock_list, bb);
6797 bblocks [bb->block_num].added = TRUE;
6801 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6802 if (!bblocks [bb->block_num].added)
6803 g_ptr_array_add (bblock_list, bb);
6807 * Second pass: generate code.
6810 LLVMBuilderRef entry_builder = create_builder (ctx);
6811 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6812 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6813 emit_entry_bb (ctx, entry_builder);
6815 // Make landing pads first
6816 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6818 if (ctx->llvm_only) {
6819 size_t group_index = 0;
6820 while (group_index < cfg->header->num_clauses) {
6822 size_t cursor = group_index;
6823 while (cursor < cfg->header->num_clauses &&
6824 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6825 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6830 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6831 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6832 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6834 group_index = cursor;
6838 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6839 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6841 // Prune unreachable mono BBs.
6842 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6845 process_bb (ctx, bb);
6849 g_hash_table_destroy (ctx->exc_meta);
6851 mono_memory_barrier ();
6853 /* Add incoming phi values */
6854 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6855 GSList *l, *ins_list;
6857 ins_list = bblocks [bb->block_num].phi_nodes;
6859 for (l = ins_list; l; l = l->next) {
6860 PhiNode *node = (PhiNode*)l->data;
6861 MonoInst *phi = node->phi;
6862 int sreg1 = node->sreg;
6863 LLVMBasicBlockRef in_bb;
6868 in_bb = get_end_bb (ctx, node->in_bb);
6870 if (ctx->unreachable [node->in_bb->block_num])
6873 if (!values [sreg1]) {
6874 /* Can happen with values in EH clauses */
6875 set_failure (ctx, "incoming phi sreg1");
6879 if (phi->opcode == OP_VPHI) {
6880 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6881 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6883 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6884 set_failure (ctx, "incoming phi arg type mismatch");
6887 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6888 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6893 /* Nullify empty phi instructions */
6894 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6895 GSList *l, *ins_list;
6897 ins_list = bblocks [bb->block_num].phi_nodes;
6899 for (l = ins_list; l; l = l->next) {
6900 PhiNode *node = (PhiNode*)l->data;
6901 MonoInst *phi = node->phi;
6902 LLVMValueRef phi_ins = values [phi->dreg];
6905 /* Already removed */
6908 if (LLVMCountIncoming (phi_ins) == 0) {
6909 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6910 LLVMInstructionEraseFromParent (phi_ins);
6911 values [phi->dreg] = NULL;
6916 /* Create the SWITCH statements for ENDFINALLY instructions */
6917 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6918 BBInfo *info = &bblocks [bb->block_num];
6920 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6921 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6922 GSList *bb_list = info->call_handler_return_bbs;
6924 for (i = 0; i < g_slist_length (bb_list); ++i)
6925 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6929 /* Initialize the method if needed */
6930 if (cfg->compile_aot && ctx->llvm_only) {
6931 // FIXME: Add more shared got entries
6932 ctx->builder = create_builder (ctx);
6933 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6935 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6937 // FIXME: beforefieldinit
6938 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6939 emit_init_method (ctx);
6941 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6945 if (cfg->llvm_only) {
6946 GHashTableIter iter;
6948 GSList *callers, *l, *l2;
6951 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6952 * We can't do this earlier, as it contains llvm instructions which can be
6953 * freed if compilation fails.
6954 * FIXME: Get rid of this when all methods can be llvm compiled.
6956 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6957 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6958 for (l = callers; l; l = l->next) {
6959 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6960 l2 = g_slist_prepend (l2, l->data);
6961 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6966 if (cfg->verbose_level > 1)
6967 mono_llvm_dump_value (method);
6969 if (cfg->compile_aot && !cfg->llvm_only)
6970 mark_as_used (ctx->module, method);
6972 if (cfg->compile_aot && !cfg->llvm_only) {
6973 LLVMValueRef md_args [16];
6974 LLVMValueRef md_node;
6977 method_index = mono_aot_get_method_index (cfg->orig_method);
6978 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6979 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6980 md_node = LLVMMDNode (md_args, 2);
6981 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6982 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6985 if (cfg->compile_aot) {
6986 /* Don't generate native code, keep the LLVM IR */
6987 if (cfg->verbose_level)
6988 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
6990 #if LLVM_API_VERSION < 100
6991 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
6992 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
6993 g_assert (err == 0);
6996 //LLVMVerifyFunction(method, 0);
6997 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
6999 if (cfg->verbose_level > 1)
7000 mono_llvm_dump_value (ctx->lmethod);
7002 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7004 /* Set by emit_cb */
7005 g_assert (cfg->code_len);
7008 if (ctx->module->method_to_lmethod)
7009 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7010 if (ctx->module->idx_to_lmethod)
7011 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7013 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7014 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7018 * mono_llvm_create_vars:
7020 * Same as mono_arch_create_vars () for LLVM.
7023 mono_llvm_create_vars (MonoCompile *cfg)
7025 MonoMethodSignature *sig;
7027 sig = mono_method_signature (cfg->method);
7028 if (cfg->gsharedvt && cfg->llvm_only) {
7029 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7030 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7031 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7032 printf ("vret_addr = ");
7033 mono_print_ins (cfg->vret_addr);
7037 mono_arch_create_vars (cfg);
7042 * mono_llvm_emit_call:
7044 * Same as mono_arch_emit_call () for LLVM.
7047 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7050 MonoMethodSignature *sig;
7051 int i, n, stack_size;
7056 sig = call->signature;
7057 n = sig->param_count + sig->hasthis;
7059 call->cinfo = get_llvm_call_info (cfg, sig);
7061 if (cfg->disable_llvm)
7064 if (sig->call_convention == MONO_CALL_VARARG) {
7065 cfg->exception_message = g_strdup ("varargs");
7066 cfg->disable_llvm = TRUE;
7069 for (i = 0; i < n; ++i) {
7072 ainfo = call->cinfo->args + i;
7074 in = call->args [i];
7076 /* Simply remember the arguments */
7077 switch (ainfo->storage) {
7078 case LLVMArgNormal: {
7079 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7082 opcode = mono_type_to_regmove (cfg, t);
7083 if (opcode == OP_FMOVE) {
7084 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7085 ins->dreg = mono_alloc_freg (cfg);
7086 } else if (opcode == OP_LMOVE) {
7087 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7088 ins->dreg = mono_alloc_lreg (cfg);
7089 } else if (opcode == OP_RMOVE) {
7090 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7091 ins->dreg = mono_alloc_freg (cfg);
7093 MONO_INST_NEW (cfg, ins, OP_MOVE);
7094 ins->dreg = mono_alloc_ireg (cfg);
7096 ins->sreg1 = in->dreg;
7099 case LLVMArgVtypeByVal:
7100 case LLVMArgVtypeByRef:
7101 case LLVMArgVtypeInReg:
7102 case LLVMArgVtypeAsScalar:
7103 case LLVMArgAsIArgs:
7104 case LLVMArgAsFpArgs:
7105 case LLVMArgGsharedvtVariable:
7106 case LLVMArgGsharedvtFixed:
7107 case LLVMArgGsharedvtFixedVtype:
7108 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7109 ins->dreg = mono_alloc_ireg (cfg);
7110 ins->sreg1 = in->dreg;
7111 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7112 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7113 ins->inst_vtype = ainfo->type;
7114 ins->klass = mono_class_from_mono_type (ainfo->type);
7117 cfg->exception_message = g_strdup ("ainfo->storage");
7118 cfg->disable_llvm = TRUE;
7122 if (!cfg->disable_llvm) {
7123 MONO_ADD_INS (cfg->cbb, ins);
7124 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7129 static unsigned char*
7130 alloc_cb (LLVMValueRef function, int size)
7134 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7138 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7140 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7145 emitted_cb (LLVMValueRef function, void *start, void *end)
7149 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7151 cfg->code_len = (guint8*)end - (guint8*)start;
7155 exception_cb (void *data)
7158 MonoJitExceptionInfo *ei;
7159 guint32 ei_len, i, j, nested_len, nindex;
7160 gpointer *type_info;
7161 int this_reg, this_offset;
7163 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7167 * data points to a DWARF FDE structure, convert it to our unwind format and
7169 * An alternative would be to save it directly, and modify our unwinder to work
7172 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);
7173 if (cfg->verbose_level > 1)
7174 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7176 /* Count nested clauses */
7178 for (i = 0; i < ei_len; ++i) {
7179 gint32 cindex1 = *(gint32*)type_info [i];
7180 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7182 for (j = 0; j < cfg->header->num_clauses; ++j) {
7184 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7186 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7192 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7193 cfg->llvm_ex_info_len = ei_len + nested_len;
7194 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7195 /* Fill the rest of the information from the type info */
7196 for (i = 0; i < ei_len; ++i) {
7197 gint32 clause_index = *(gint32*)type_info [i];
7198 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7200 cfg->llvm_ex_info [i].flags = clause->flags;
7201 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7202 cfg->llvm_ex_info [i].clause_index = clause_index;
7206 * For nested clauses, the LLVM produced exception info associates the try interval with
7207 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7208 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7209 * and everything else from the nested clause.
7212 for (i = 0; i < ei_len; ++i) {
7213 gint32 cindex1 = *(gint32*)type_info [i];
7214 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7216 for (j = 0; j < cfg->header->num_clauses; ++j) {
7218 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7219 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7221 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7222 /* clause1 is the nested clause */
7223 nested_ei = &cfg->llvm_ex_info [i];
7224 nesting_ei = &cfg->llvm_ex_info [nindex];
7227 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7229 nesting_ei->flags = clause2->flags;
7230 nesting_ei->data.catch_class = clause2->data.catch_class;
7231 nesting_ei->clause_index = cindex2;
7235 g_assert (nindex == ei_len + nested_len);
7236 cfg->llvm_this_reg = this_reg;
7237 cfg->llvm_this_offset = this_offset;
7239 /* type_info [i] is cfg mempool allocated, no need to free it */
7246 dlsym_cb (const char *name, void **symbol)
7252 if (!strcmp (name, "__bzero")) {
7253 *symbol = (void*)bzero;
7255 current = mono_dl_open (NULL, 0, NULL);
7258 err = mono_dl_symbol (current, name, symbol);
7260 mono_dl_close (current);
7262 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7263 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7269 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7271 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7275 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7277 LLVMTypeRef param_types [4];
7279 param_types [0] = param_type1;
7280 param_types [1] = param_type2;
7282 AddFunc (module, name, ret_type, param_types, 2);
7286 add_intrinsics (LLVMModuleRef module)
7288 /* Emit declarations of instrinsics */
7290 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7291 * type doesn't seem to do any locking.
7294 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7296 memset_param_count = 5;
7297 memset_func_name = "llvm.memset.p0i8.i32";
7299 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7303 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7305 memcpy_param_count = 5;
7306 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7308 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7312 LLVMTypeRef params [] = { LLVMDoubleType () };
7314 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7315 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7316 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7318 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7319 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7323 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7324 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7325 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7327 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7328 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7329 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7330 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7331 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7332 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7333 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7337 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7338 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7339 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7341 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7342 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7343 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7344 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7345 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7346 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7349 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7350 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7354 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7356 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7359 /* SSE intrinsics */
7360 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7362 LLVMTypeRef ret_type, arg_types [16];
7365 ret_type = type_to_simd_type (MONO_TYPE_I4);
7366 arg_types [0] = ret_type;
7367 arg_types [1] = ret_type;
7368 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7369 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7371 ret_type = type_to_simd_type (MONO_TYPE_I2);
7372 arg_types [0] = ret_type;
7373 arg_types [1] = ret_type;
7374 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7375 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7376 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7377 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7378 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7379 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7380 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7382 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7383 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7385 ret_type = type_to_simd_type (MONO_TYPE_I1);
7386 arg_types [0] = ret_type;
7387 arg_types [1] = ret_type;
7388 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7389 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7390 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7391 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7392 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7394 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7396 ret_type = type_to_simd_type (MONO_TYPE_R8);
7397 arg_types [0] = ret_type;
7398 arg_types [1] = ret_type;
7399 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7400 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7401 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7402 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7403 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7405 ret_type = type_to_simd_type (MONO_TYPE_R4);
7406 arg_types [0] = ret_type;
7407 arg_types [1] = ret_type;
7408 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7409 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7410 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7411 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7412 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7415 ret_type = type_to_simd_type (MONO_TYPE_I1);
7416 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7417 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7418 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7419 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7420 ret_type = type_to_simd_type (MONO_TYPE_I2);
7421 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7422 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7423 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7424 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7427 ret_type = type_to_simd_type (MONO_TYPE_R8);
7428 arg_types [0] = ret_type;
7429 arg_types [1] = ret_type;
7430 arg_types [2] = LLVMInt8Type ();
7431 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7432 ret_type = type_to_simd_type (MONO_TYPE_R4);
7433 arg_types [0] = ret_type;
7434 arg_types [1] = ret_type;
7435 arg_types [2] = LLVMInt8Type ();
7436 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7438 /* Conversion ops */
7439 ret_type = type_to_simd_type (MONO_TYPE_R8);
7440 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7441 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7442 ret_type = type_to_simd_type (MONO_TYPE_R4);
7443 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7444 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7445 ret_type = type_to_simd_type (MONO_TYPE_I4);
7446 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7447 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7448 ret_type = type_to_simd_type (MONO_TYPE_I4);
7449 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7450 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7451 ret_type = type_to_simd_type (MONO_TYPE_R4);
7452 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7453 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7454 ret_type = type_to_simd_type (MONO_TYPE_R8);
7455 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7456 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7458 ret_type = type_to_simd_type (MONO_TYPE_I4);
7459 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7460 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7461 ret_type = type_to_simd_type (MONO_TYPE_I4);
7462 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7463 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7466 ret_type = type_to_simd_type (MONO_TYPE_R8);
7467 arg_types [0] = ret_type;
7468 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7469 ret_type = type_to_simd_type (MONO_TYPE_R4);
7470 arg_types [0] = ret_type;
7471 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7472 ret_type = type_to_simd_type (MONO_TYPE_R4);
7473 arg_types [0] = ret_type;
7474 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7475 ret_type = type_to_simd_type (MONO_TYPE_R4);
7476 arg_types [0] = ret_type;
7477 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7480 ret_type = type_to_simd_type (MONO_TYPE_I2);
7481 arg_types [0] = ret_type;
7482 arg_types [1] = LLVMInt32Type ();
7483 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7484 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7485 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7486 ret_type = type_to_simd_type (MONO_TYPE_I4);
7487 arg_types [0] = ret_type;
7488 arg_types [1] = LLVMInt32Type ();
7489 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7490 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7491 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7492 ret_type = type_to_simd_type (MONO_TYPE_I8);
7493 arg_types [0] = ret_type;
7494 arg_types [1] = LLVMInt32Type ();
7495 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7496 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7499 ret_type = LLVMInt32Type ();
7500 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7501 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7504 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7507 /* Load/Store intrinsics */
7509 LLVMTypeRef arg_types [5];
7513 for (i = 1; i <= 8; i *= 2) {
7514 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7515 arg_types [1] = LLVMInt32Type ();
7516 arg_types [2] = LLVMInt1Type ();
7517 arg_types [3] = LLVMInt32Type ();
7518 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7519 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7521 arg_types [0] = LLVMIntType (i * 8);
7522 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7523 arg_types [2] = LLVMInt32Type ();
7524 arg_types [3] = LLVMInt1Type ();
7525 arg_types [4] = LLVMInt32Type ();
7526 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7527 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7533 add_types (MonoLLVMModule *module)
7535 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7539 mono_llvm_init (void)
7541 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7545 init_jit_module (MonoDomain *domain)
7547 MonoJitICallInfo *info;
7548 MonoJitDomainInfo *dinfo;
7549 MonoLLVMModule *module;
7552 dinfo = domain_jit_info (domain);
7553 if (dinfo->llvm_module)
7556 mono_loader_lock ();
7558 if (dinfo->llvm_module) {
7559 mono_loader_unlock ();
7563 module = g_new0 (MonoLLVMModule, 1);
7565 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7566 module->lmodule = LLVMModuleCreateWithName (name);
7567 module->context = LLVMGetGlobalContext ();
7569 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7571 add_intrinsics (module->lmodule);
7574 module->llvm_types = g_hash_table_new (NULL, NULL);
7576 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7578 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7580 mono_memory_barrier ();
7582 dinfo->llvm_module = module;
7584 mono_loader_unlock ();
7588 mono_llvm_cleanup (void)
7590 MonoLLVMModule *module = &aot_module;
7592 if (module->lmodule)
7593 LLVMDisposeModule (module->lmodule);
7595 if (module->context)
7596 LLVMContextDispose (module->context);
7600 mono_llvm_free_domain_info (MonoDomain *domain)
7602 MonoJitDomainInfo *info = domain_jit_info (domain);
7603 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7609 if (module->llvm_types)
7610 g_hash_table_destroy (module->llvm_types);
7612 mono_llvm_dispose_ee (module->mono_ee);
7614 if (module->bb_names) {
7615 for (i = 0; i < module->bb_names_len; ++i)
7616 g_free (module->bb_names [i]);
7617 g_free (module->bb_names);
7619 //LLVMDisposeModule (module->module);
7623 info->llvm_module = NULL;
7627 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7629 MonoLLVMModule *module = &aot_module;
7631 /* Delete previous module */
7632 if (module->plt_entries)
7633 g_hash_table_destroy (module->plt_entries);
7634 if (module->lmodule)
7635 LLVMDisposeModule (module->lmodule);
7637 memset (module, 0, sizeof (aot_module));
7639 module->lmodule = LLVMModuleCreateWithName ("aot");
7640 module->assembly = assembly;
7641 module->global_prefix = g_strdup (global_prefix);
7642 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7643 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7644 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7645 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7646 module->external_symbols = TRUE;
7647 module->emit_dwarf = emit_dwarf;
7648 module->static_link = static_link;
7649 module->llvm_only = llvm_only;
7650 /* The first few entries are reserved */
7651 module->max_got_offset = 16;
7652 module->context = LLVMContextCreate ();
7655 /* clang ignores our debug info because it has an invalid version */
7656 module->emit_dwarf = FALSE;
7658 #if LLVM_API_VERSION > 100
7659 module->emit_dwarf = FALSE;
7662 add_intrinsics (module->lmodule);
7665 #if LLVM_API_VERSION > 100
7666 if (module->emit_dwarf) {
7667 char *dir, *build_info, *s, *cu_name;
7669 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
7672 dir = g_strdup (".");
7673 build_info = mono_get_runtime_build_info ();
7674 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7675 cu_name = g_path_get_basename (assembly->image->name);
7676 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
7678 g_free (build_info);
7685 * We couldn't compute the type of the LLVM global representing the got because
7686 * its size is only known after all the methods have been emitted. So create
7687 * a dummy variable, and replace all uses it with the real got variable when
7688 * its size is known in mono_llvm_emit_aot_module ().
7691 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7693 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7694 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7697 /* Add initialization array */
7699 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7701 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7702 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7706 emit_init_icall_wrappers (module);
7708 emit_llvm_code_start (module);
7710 /* Add a dummy personality function */
7711 if (!use_debug_personality) {
7712 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7713 LLVMSetLinkage (personality, LLVMExternalLinkage);
7714 mark_as_used (module, personality);
7717 /* Add a reference to the c++ exception we throw/catch */
7719 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7720 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7721 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7722 mono_llvm_set_is_constant (module->sentinel_exception);
7725 module->llvm_types = g_hash_table_new (NULL, NULL);
7726 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7727 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7728 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7729 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7730 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7731 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7732 module->method_to_callers = g_hash_table_new (NULL, NULL);
7736 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7739 LLVMValueRef res, *vals;
7741 vals = g_new0 (LLVMValueRef, nvalues);
7742 for (i = 0; i < nvalues; ++i)
7743 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7744 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7750 * mono_llvm_emit_aot_file_info:
7752 * Emit the MonoAotFileInfo structure.
7753 * Same as emit_aot_file_info () in aot-compiler.c.
7756 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7758 MonoLLVMModule *module = &aot_module;
7760 /* Save these for later */
7761 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7762 module->has_jitted_code = has_jitted_code;
7766 * mono_llvm_emit_aot_data:
7768 * Emit the binary data DATA pointed to by symbol SYMBOL.
7771 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7773 MonoLLVMModule *module = &aot_module;
7777 type = LLVMArrayType (LLVMInt8Type (), data_len);
7778 d = LLVMAddGlobal (module->lmodule, type, symbol);
7779 LLVMSetVisibility (d, LLVMHiddenVisibility);
7780 LLVMSetLinkage (d, LLVMInternalLinkage);
7781 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7782 mono_llvm_set_is_constant (d);
7785 /* Add a reference to a global defined in JITted code */
7787 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7792 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7793 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7799 emit_aot_file_info (MonoLLVMModule *module)
7801 LLVMTypeRef file_info_type;
7802 LLVMTypeRef *eltypes, eltype;
7803 LLVMValueRef info_var;
7804 LLVMValueRef *fields;
7805 int i, nfields, tindex;
7806 MonoAotFileInfo *info;
7807 LLVMModuleRef lmodule = module->lmodule;
7809 info = &module->aot_info;
7811 /* Create an LLVM type to represent MonoAotFileInfo */
7812 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7813 eltypes = g_new (LLVMTypeRef, nfields);
7815 eltypes [tindex ++] = LLVMInt32Type ();
7816 eltypes [tindex ++] = LLVMInt32Type ();
7818 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7819 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7821 for (i = 0; i < 15; ++i)
7822 eltypes [tindex ++] = LLVMInt32Type ();
7824 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7825 for (i = 0; i < 4; ++i)
7826 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7827 g_assert (tindex == nfields);
7828 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7829 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7831 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7832 if (module->static_link) {
7833 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7834 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7836 fields = g_new (LLVMValueRef, nfields);
7838 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7839 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7843 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7844 * for symbols defined in the .s file emitted by the aot compiler.
7846 eltype = eltypes [tindex];
7847 if (module->llvm_only)
7848 fields [tindex ++] = LLVMConstNull (eltype);
7850 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7851 fields [tindex ++] = module->got_var;
7852 /* llc defines this directly */
7853 if (!module->llvm_only) {
7854 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7855 fields [tindex ++] = LLVMConstNull (eltype);
7856 fields [tindex ++] = LLVMConstNull (eltype);
7858 fields [tindex ++] = LLVMConstNull (eltype);
7859 fields [tindex ++] = module->get_method;
7860 fields [tindex ++] = module->get_unbox_tramp;
7862 if (module->has_jitted_code) {
7863 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7864 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7866 fields [tindex ++] = LLVMConstNull (eltype);
7867 fields [tindex ++] = LLVMConstNull (eltype);
7869 if (!module->llvm_only)
7870 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7872 fields [tindex ++] = LLVMConstNull (eltype);
7873 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7874 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7875 fields [tindex ++] = LLVMConstNull (eltype);
7877 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7878 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7879 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7880 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7881 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7882 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7883 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7884 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7885 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7886 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7888 /* Not needed (mem_end) */
7889 fields [tindex ++] = LLVMConstNull (eltype);
7890 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7891 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7892 if (info->trampoline_size [0]) {
7893 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7894 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7895 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7896 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7898 fields [tindex ++] = LLVMConstNull (eltype);
7899 fields [tindex ++] = LLVMConstNull (eltype);
7900 fields [tindex ++] = LLVMConstNull (eltype);
7901 fields [tindex ++] = LLVMConstNull (eltype);
7903 if (module->static_link && !module->llvm_only)
7904 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7906 fields [tindex ++] = LLVMConstNull (eltype);
7907 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7908 if (!module->llvm_only) {
7909 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7910 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7911 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7912 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7913 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7914 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7916 fields [tindex ++] = LLVMConstNull (eltype);
7917 fields [tindex ++] = LLVMConstNull (eltype);
7918 fields [tindex ++] = LLVMConstNull (eltype);
7919 fields [tindex ++] = LLVMConstNull (eltype);
7920 fields [tindex ++] = LLVMConstNull (eltype);
7921 fields [tindex ++] = LLVMConstNull (eltype);
7924 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7925 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7928 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7929 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7930 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7931 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7932 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7933 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7934 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7935 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7936 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7937 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7938 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7939 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7940 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7941 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7942 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7944 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7945 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7946 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7947 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7948 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7949 g_assert (tindex == nfields);
7951 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7953 if (module->static_link) {
7957 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7958 /* Get rid of characters which cannot occur in symbols */
7960 for (p = s; *p; ++p) {
7961 if (!(isalnum (*p) || *p == '_'))
7964 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7966 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7967 LLVMSetLinkage (var, LLVMExternalLinkage);
7972 * Emit the aot module into the LLVM bitcode file FILENAME.
7975 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7977 LLVMTypeRef got_type, inited_type;
7978 LLVMValueRef real_got, real_inited;
7979 MonoLLVMModule *module = &aot_module;
7981 emit_llvm_code_end (module);
7984 * Create the real got variable and replace all uses of the dummy variable with
7987 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7988 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7989 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7990 if (module->external_symbols) {
7991 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7992 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7994 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7996 mono_llvm_replace_uses_of (module->got_var, real_got);
7998 mark_as_used (&aot_module, real_got);
8000 /* Delete the dummy got so it doesn't become a global */
8001 LLVMDeleteGlobal (module->got_var);
8002 module->got_var = real_got;
8005 * Same for the init_var
8007 if (module->llvm_only) {
8008 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8009 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8010 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8011 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8012 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8013 LLVMDeleteGlobal (module->inited_var);
8016 if (module->llvm_only) {
8017 emit_get_method (&aot_module);
8018 emit_get_unbox_tramp (&aot_module);
8021 emit_llvm_used (&aot_module);
8022 emit_dbg_info (&aot_module, filename, cu_name);
8023 emit_aot_file_info (&aot_module);
8026 * Replace GOT entries for directly callable methods with the methods themselves.
8027 * It would be easier to implement this by predefining all methods before compiling
8028 * their bodies, but that couldn't handle the case when a method fails to compile
8031 if (module->llvm_only) {
8032 GHashTableIter iter;
8034 GSList *callers, *l;
8036 g_hash_table_iter_init (&iter, module->method_to_callers);
8037 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8038 LLVMValueRef lmethod;
8040 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8042 for (l = callers; l; l = l->next) {
8043 LLVMValueRef caller = (LLVMValueRef)l->data;
8045 mono_llvm_replace_uses_of (caller, lmethod);
8051 /* Replace PLT entries for directly callable methods with the methods themselves */
8053 GHashTableIter iter;
8055 LLVMValueRef callee;
8057 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8058 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8059 if (mono_aot_is_direct_callable (ji)) {
8060 LLVMValueRef lmethod;
8062 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8063 /* The types might not match because the caller might pass an rgctx */
8064 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8065 mono_llvm_replace_uses_of (callee, lmethod);
8066 mono_aot_mark_unused_llvm_plt_entry (ji);
8076 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8077 g_assert_not_reached ();
8082 LLVMWriteBitcodeToFile (module->lmodule, filename);
8087 md_string (const char *s)
8089 return LLVMMDString (s, strlen (s));
8092 /* Debugging support */
8095 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8097 LLVMModuleRef lmodule = module->lmodule;
8098 LLVMValueRef args [16], ver;
8101 * This can only be enabled when LLVM code is emitted into a separate object
8102 * file, since the AOT compiler also emits dwarf info,
8103 * and the abbrev indexes will not be correct since llvm has added its own
8106 if (!module->emit_dwarf)
8109 #if LLVM_API_VERSION > 100
8110 mono_llvm_di_builder_finalize (module->di_builder);
8112 LLVMValueRef cu_args [16], cu;
8114 char *build_info, *s, *dir;
8117 * Emit dwarf info in the form of LLVM metadata. There is some
8118 * out-of-date documentation at:
8119 * http://llvm.org/docs/SourceLevelDebugging.html
8120 * but most of this was gathered from the llvm and
8125 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8126 /* CU name/compilation dir */
8127 dir = g_path_get_dirname (filename);
8128 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8129 args [1] = LLVMMDString (dir, strlen (dir));
8130 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8133 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8135 build_info = mono_get_runtime_build_info ();
8136 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8137 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8138 g_free (build_info);
8140 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8142 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8143 /* Runtime version */
8144 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8146 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8147 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8149 if (module->subprogram_mds) {
8153 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8154 for (i = 0; i < module->subprogram_mds->len; ++i)
8155 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8156 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8158 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8161 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8162 /* Imported modules */
8163 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8165 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8166 /* DebugEmissionKind = FullDebug */
8167 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8168 cu = LLVMMDNode (cu_args, n_cuargs);
8169 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8172 #if LLVM_API_VERSION > 100
8173 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8174 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8175 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8176 ver = LLVMMDNode (args, 3);
8177 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8179 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8180 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8181 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8182 ver = LLVMMDNode (args, 3);
8183 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8185 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8186 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8187 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8188 ver = LLVMMDNode (args, 3);
8189 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8191 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8192 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8193 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8194 ver = LLVMMDNode (args, 3);
8195 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8200 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8202 MonoLLVMModule *module = ctx->module;
8203 MonoDebugMethodInfo *minfo = ctx->minfo;
8204 char *source_file, *dir, *filename;
8205 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8206 MonoSymSeqPoint *sym_seq_points;
8212 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8214 source_file = g_strdup ("<unknown>");
8215 dir = g_path_get_dirname (source_file);
8216 filename = g_path_get_basename (source_file);
8218 #if LLVM_API_VERSION > 100
8219 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);
8222 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8223 args [0] = md_string (filename);
8224 args [1] = md_string (dir);
8225 ctx_args [1] = LLVMMDNode (args, 2);
8226 ctx_md = LLVMMDNode (ctx_args, 2);
8228 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8229 type_args [1] = NULL;
8230 type_args [2] = NULL;
8231 type_args [3] = LLVMMDString ("", 0);
8232 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8233 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8234 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8235 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8236 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8237 type_args [9] = NULL;
8238 type_args [10] = NULL;
8239 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8240 type_args [12] = NULL;
8241 type_args [13] = NULL;
8242 type_args [14] = NULL;
8243 type_md = LLVMMDNode (type_args, 14);
8245 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8246 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8247 /* Source directory + file pair */
8248 args [0] = md_string (filename);
8249 args [1] = md_string (dir);
8250 md_args [1] = LLVMMDNode (args ,2);
8251 md_args [2] = ctx_md;
8252 md_args [3] = md_string (cfg->method->name);
8253 md_args [4] = md_string (name);
8254 md_args [5] = md_string (name);
8257 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8259 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8261 md_args [7] = type_md;
8263 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8265 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8267 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8268 /* Index into a virtual function */
8269 md_args [11] = NULL;
8270 md_args [12] = NULL;
8272 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8274 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8275 /* Pointer to LLVM function */
8276 md_args [15] = method;
8277 /* Function template parameter */
8278 md_args [16] = NULL;
8279 /* Function declaration descriptor */
8280 md_args [17] = NULL;
8281 /* List of function variables */
8282 md_args [18] = LLVMMDNode (args, 0);
8284 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8285 md = LLVMMDNode (md_args, 20);
8287 if (!module->subprogram_mds)
8288 module->subprogram_mds = g_ptr_array_new ();
8289 g_ptr_array_add (module->subprogram_mds, md);
8293 g_free (source_file);
8294 g_free (sym_seq_points);
8300 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8302 MonoCompile *cfg = ctx->cfg;
8304 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8305 MonoDebugSourceLocation *loc;
8306 LLVMValueRef loc_md;
8308 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8311 #if LLVM_API_VERSION > 100
8312 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8313 mono_llvm_di_set_location (builder, loc_md);
8315 LLVMValueRef md_args [16];
8319 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8320 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8321 md_args [nmd_args ++] = ctx->dbg_md;
8322 md_args [nmd_args ++] = NULL;
8323 loc_md = LLVMMDNode (md_args, nmd_args);
8324 LLVMSetCurrentDebugLocation (builder, loc_md);
8326 mono_debug_symfile_free_location (loc);
8332 default_mono_llvm_unhandled_exception (void)
8334 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8335 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8337 mono_unhandled_exception (target);
8338 exit (mono_environment_exitcode_get ());
8343 - Emit LLVM IR from the mono IR using the LLVM C API.
8344 - The original arch specific code remains, so we can fall back to it if we run
8345 into something we can't handle.
8349 A partial list of issues:
8350 - Handling of opcodes which can throw exceptions.
8352 In the mono JIT, these are implemented using code like this:
8359 push throw_pos - method
8360 call <exception trampoline>
8362 The problematic part is push throw_pos - method, which cannot be represented
8363 in the LLVM IR, since it does not support label values.
8364 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8365 be implemented in JIT mode ?
8366 -> a possible but slower implementation would use the normal exception
8367 throwing code but it would need to control the placement of the throw code
8368 (it needs to be exactly after the compare+branch).
8369 -> perhaps add a PC offset intrinsics ?
8371 - efficient implementation of .ovf opcodes.
8373 These are currently implemented as:
8374 <ins which sets the condition codes>
8377 Some overflow opcodes are now supported by LLVM SVN.
8379 - exception handling, unwinding.
8380 - SSA is disabled for methods with exception handlers
8381 - How to obtain unwind info for LLVM compiled methods ?
8382 -> this is now solved by converting the unwind info generated by LLVM
8384 - LLVM uses the c++ exception handling framework, while we use our home grown
8385 code, and couldn't use the c++ one:
8386 - its not supported under VC++, other exotic platforms.
8387 - it might be impossible to support filter clauses with it.
8391 The trampolines need a predictable call sequence, since they need to disasm
8392 the calling code to obtain register numbers / offsets.
8394 LLVM currently generates this code in non-JIT mode:
8395 mov -0x98(%rax),%eax
8397 Here, the vtable pointer is lost.
8398 -> solution: use one vtable trampoline per class.
8400 - passing/receiving the IMT pointer/RGCTX.
8401 -> solution: pass them as normal arguments ?
8405 LLVM does not allow the specification of argument registers etc. This means
8406 that all calls are made according to the platform ABI.
8408 - passing/receiving vtypes.
8410 Vtypes passed/received in registers are handled by the front end by using
8411 a signature with scalar arguments, and loading the parts of the vtype into those
8414 Vtypes passed on the stack are handled using the 'byval' attribute.
8418 Supported though alloca, we need to emit the load/store code.
8422 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8423 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8424 This is made easier because the IR is already in SSA form.
8425 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8426 types are frequently used incorrectly.
8431 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8432 it with the file containing the methods emitted by the JIT and the AOT data
8436 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8437 * - each bblock should end with a branch
8438 * - setting the return value, making cfg->ret non-volatile
8439 * - avoid some transformations in the JIT which make it harder for us to generate
8441 * - use pointer types to help optimizations.