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/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 LLVMValueRef generic_class_init_tramp;
50 GHashTable *llvm_types;
52 const char *got_symbol;
53 GHashTable *plt_entries;
54 GHashTable *plt_entries_ji;
55 GHashTable *method_to_lmethod;
60 GPtrArray *subprogram_mds;
62 LLVMExecutionEngineRef ee;
63 gboolean external_symbols;
69 * Information associated by the backend with mono basic blocks.
72 LLVMBasicBlockRef bblock, end_bblock;
73 LLVMValueRef finally_ind;
74 gboolean added, invoke_target;
76 * If this bblock is the start of a finally clause, this is a list of bblocks it
77 * needs to branch to in ENDFINALLY.
79 GSList *call_handler_return_bbs;
81 * If this bblock is the start of a finally clause, this is the bblock that
82 * CALL_HANDLER needs to branch to.
84 LLVMBasicBlockRef call_handler_target_bb;
85 /* The list of switch statements generated by ENDFINALLY instructions */
86 GSList *endfinally_switch_ins_list;
91 * Structure containing emit state
96 /* Maps method names to the corresponding LLVMValueRef */
97 GHashTable *emitted_method_decls;
100 LLVMValueRef lmethod;
101 MonoLLVMModule *lmodule;
102 LLVMModuleRef module;
104 int sindex, default_index, ex_index;
105 LLVMBuilderRef builder;
106 LLVMValueRef *values, *addresses;
107 MonoType **vreg_cli_types;
109 MonoMethodSignature *sig;
111 GHashTable *region_to_handler;
112 GHashTable *clause_to_handler;
113 LLVMBuilderRef alloca_builder;
114 LLVMValueRef last_alloca;
115 LLVMValueRef rgctx_arg;
116 LLVMTypeRef *vreg_types;
118 gboolean *unreachable;
120 LLVMValueRef imt_rgctx_loc;
121 GHashTable *llvm_types;
123 MonoDebugMethodInfo *minfo;
125 /* For every clause, the clauses it is nested in */
133 MonoBasicBlock *in_bb;
138 * Instruction metadata
139 * This is the same as ins_info, but LREG != IREG.
147 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
148 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
155 /* keep in sync with the enum in mini.h */
158 #include "mini-ops.h"
163 #if SIZEOF_VOID_P == 4
164 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
166 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
169 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
172 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
174 #define TRACE_FAILURE(msg)
178 #define IS_TARGET_X86 1
180 #define IS_TARGET_X86 0
184 #define IS_TARGET_AMD64 1
186 #define IS_TARGET_AMD64 0
189 #define LLVM_FAILURE(ctx, reason) do { \
190 TRACE_FAILURE (reason); \
191 (ctx)->cfg->exception_message = g_strdup (reason); \
192 (ctx)->cfg->disable_llvm = TRUE; \
196 #define CHECK_FAILURE(ctx) do { \
197 if ((ctx)->cfg->disable_llvm) \
201 static LLVMIntPredicate cond_to_llvm_cond [] = {
214 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
227 static MonoNativeTlsKey current_cfg_tls_id;
229 static MonoLLVMModule aot_module;
230 static int memset_param_count, memcpy_param_count;
231 static const char *memset_func_name;
232 static const char *memcpy_func_name;
234 static void init_jit_module (MonoDomain *domain);
236 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
237 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
238 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
243 * The LLVM type with width == sizeof (gpointer)
248 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
254 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
260 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
266 * Return the size of the LLVM representation of the vtype T.
269 get_vtype_size (MonoType *t)
273 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
275 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
282 * simd_class_to_llvm_type:
284 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
287 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
289 if (!strcmp (klass->name, "Vector2d")) {
290 return LLVMVectorType (LLVMDoubleType (), 2);
291 } else if (!strcmp (klass->name, "Vector2l")) {
292 return LLVMVectorType (LLVMInt64Type (), 2);
293 } else if (!strcmp (klass->name, "Vector2ul")) {
294 return LLVMVectorType (LLVMInt64Type (), 2);
295 } else if (!strcmp (klass->name, "Vector4i")) {
296 return LLVMVectorType (LLVMInt32Type (), 4);
297 } else if (!strcmp (klass->name, "Vector4ui")) {
298 return LLVMVectorType (LLVMInt32Type (), 4);
299 } else if (!strcmp (klass->name, "Vector4f")) {
300 return LLVMVectorType (LLVMFloatType (), 4);
301 } else if (!strcmp (klass->name, "Vector8s")) {
302 return LLVMVectorType (LLVMInt16Type (), 8);
303 } else if (!strcmp (klass->name, "Vector8us")) {
304 return LLVMVectorType (LLVMInt16Type (), 8);
305 } else if (!strcmp (klass->name, "Vector16sb")) {
306 return LLVMVectorType (LLVMInt8Type (), 16);
307 } else if (!strcmp (klass->name, "Vector16b")) {
308 return LLVMVectorType (LLVMInt8Type (), 16);
310 printf ("%s\n", klass->name);
316 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
317 static inline G_GNUC_UNUSED LLVMTypeRef
318 type_to_simd_type (int type)
322 return LLVMVectorType (LLVMInt8Type (), 16);
324 return LLVMVectorType (LLVMInt16Type (), 8);
326 return LLVMVectorType (LLVMInt32Type (), 4);
328 return LLVMVectorType (LLVMInt64Type (), 2);
330 return LLVMVectorType (LLVMDoubleType (), 2);
332 return LLVMVectorType (LLVMFloatType (), 4);
334 g_assert_not_reached ();
340 create_llvm_type_for_type (MonoClass *klass)
342 int i, size, nfields, esize;
343 LLVMTypeRef *eltypes;
348 t = &klass->byval_arg;
350 if (mini_type_is_hfa (t, &nfields, &esize)) {
352 * This is needed on arm64 where HFAs are returned in
356 eltypes = g_new (LLVMTypeRef, size);
357 for (i = 0; i < size; ++i)
358 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
360 size = get_vtype_size (t);
362 eltypes = g_new (LLVMTypeRef, size);
363 for (i = 0; i < size; ++i)
364 eltypes [i] = LLVMInt8Type ();
367 name = mono_type_full_name (&klass->byval_arg);
368 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
369 LLVMStructSetBody (ltype, eltypes, size, FALSE);
379 * Return the LLVM type corresponding to T.
382 type_to_llvm_type (EmitContext *ctx, MonoType *t)
385 return LLVMPointerType (LLVMInt8Type (), 0);
387 t = mini_get_underlying_type (ctx->cfg, t);
390 return LLVMVoidType ();
392 return LLVMInt8Type ();
394 return LLVMInt16Type ();
396 return LLVMInt32Type ();
398 return LLVMInt8Type ();
400 return LLVMInt16Type ();
402 return LLVMInt32Type ();
403 case MONO_TYPE_BOOLEAN:
404 return LLVMInt8Type ();
407 return LLVMInt64Type ();
409 return LLVMInt16Type ();
411 return LLVMFloatType ();
413 return LLVMDoubleType ();
416 return IntPtrType ();
417 case MONO_TYPE_OBJECT:
418 case MONO_TYPE_CLASS:
419 case MONO_TYPE_ARRAY:
420 case MONO_TYPE_SZARRAY:
421 case MONO_TYPE_STRING:
423 return ObjRefType ();
426 /* Because of generic sharing */
427 return ObjRefType ();
428 case MONO_TYPE_GENERICINST:
429 if (!mono_type_generic_inst_is_valuetype (t))
430 return ObjRefType ();
432 case MONO_TYPE_VALUETYPE:
433 case MONO_TYPE_TYPEDBYREF: {
437 klass = mono_class_from_mono_type (t);
439 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
440 return simd_class_to_llvm_type (ctx, klass);
443 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
445 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
447 ltype = create_llvm_type_for_type (klass);
448 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
454 printf ("X: %d\n", t->type);
455 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
456 ctx->cfg->disable_llvm = TRUE;
464 * Return whenever T is an unsigned int type.
467 type_is_unsigned (EmitContext *ctx, MonoType *t)
484 * type_to_llvm_arg_type:
486 * Same as type_to_llvm_type, but treat i8/i16 as i32.
489 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
491 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
494 * This works on all abis except arm64/ios which passes multiple
495 * arguments in one stack slot.
498 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
500 * LLVM generates code which only sets the lower bits, while JITted
501 * code expects all the bits to be set.
503 ptype = LLVMInt32Type ();
511 * llvm_type_to_stack_type:
513 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
516 static G_GNUC_UNUSED LLVMTypeRef
517 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
521 if (type == LLVMInt8Type ())
522 return LLVMInt32Type ();
523 else if (type == LLVMInt16Type ())
524 return LLVMInt32Type ();
525 else if (!cfg->r4fp && type == LLVMFloatType ())
526 return LLVMDoubleType ();
532 * regtype_to_llvm_type:
534 * Return the LLVM type corresponding to the regtype C used in instruction
538 regtype_to_llvm_type (char c)
542 return LLVMInt32Type ();
544 return LLVMInt64Type ();
546 return LLVMDoubleType ();
555 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
558 op_to_llvm_type (int opcode)
563 return LLVMInt8Type ();
566 return LLVMInt8Type ();
569 return LLVMInt16Type ();
572 return LLVMInt16Type ();
575 return LLVMInt32Type ();
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMFloatType ();
584 return LLVMDoubleType ();
586 return LLVMInt64Type ();
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
595 return LLVMInt8Type ();
600 return LLVMInt16Type ();
603 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
610 return LLVMInt32Type ();
617 return LLVMInt64Type ();
619 printf ("%s\n", mono_inst_name (opcode));
620 g_assert_not_reached ();
626 * load_store_to_llvm_type:
628 * Return the size/sign/zero extension corresponding to the load/store opcode
632 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
638 case OP_LOADI1_MEMBASE:
639 case OP_STOREI1_MEMBASE_REG:
640 case OP_STOREI1_MEMBASE_IMM:
641 case OP_ATOMIC_LOAD_I1:
642 case OP_ATOMIC_STORE_I1:
645 return LLVMInt8Type ();
646 case OP_LOADU1_MEMBASE:
648 case OP_ATOMIC_LOAD_U1:
649 case OP_ATOMIC_STORE_U1:
652 return LLVMInt8Type ();
653 case OP_LOADI2_MEMBASE:
654 case OP_STOREI2_MEMBASE_REG:
655 case OP_STOREI2_MEMBASE_IMM:
656 case OP_ATOMIC_LOAD_I2:
657 case OP_ATOMIC_STORE_I2:
660 return LLVMInt16Type ();
661 case OP_LOADU2_MEMBASE:
663 case OP_ATOMIC_LOAD_U2:
664 case OP_ATOMIC_STORE_U2:
667 return LLVMInt16Type ();
668 case OP_LOADI4_MEMBASE:
669 case OP_LOADU4_MEMBASE:
672 case OP_STOREI4_MEMBASE_REG:
673 case OP_STOREI4_MEMBASE_IMM:
674 case OP_ATOMIC_LOAD_I4:
675 case OP_ATOMIC_STORE_I4:
676 case OP_ATOMIC_LOAD_U4:
677 case OP_ATOMIC_STORE_U4:
679 return LLVMInt32Type ();
680 case OP_LOADI8_MEMBASE:
682 case OP_STOREI8_MEMBASE_REG:
683 case OP_STOREI8_MEMBASE_IMM:
684 case OP_ATOMIC_LOAD_I8:
685 case OP_ATOMIC_STORE_I8:
686 case OP_ATOMIC_LOAD_U8:
687 case OP_ATOMIC_STORE_U8:
689 return LLVMInt64Type ();
690 case OP_LOADR4_MEMBASE:
691 case OP_STORER4_MEMBASE_REG:
692 case OP_ATOMIC_LOAD_R4:
693 case OP_ATOMIC_STORE_R4:
695 return LLVMFloatType ();
696 case OP_LOADR8_MEMBASE:
697 case OP_STORER8_MEMBASE_REG:
698 case OP_ATOMIC_LOAD_R8:
699 case OP_ATOMIC_STORE_R8:
701 return LLVMDoubleType ();
702 case OP_LOAD_MEMBASE:
704 case OP_STORE_MEMBASE_REG:
705 case OP_STORE_MEMBASE_IMM:
706 *size = sizeof (gpointer);
707 return IntPtrType ();
709 g_assert_not_reached ();
717 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
720 ovf_op_to_intrins (int opcode)
724 return "llvm.sadd.with.overflow.i32";
726 return "llvm.uadd.with.overflow.i32";
728 return "llvm.ssub.with.overflow.i32";
730 return "llvm.usub.with.overflow.i32";
732 return "llvm.smul.with.overflow.i32";
734 return "llvm.umul.with.overflow.i32";
736 return "llvm.sadd.with.overflow.i64";
738 return "llvm.uadd.with.overflow.i64";
740 return "llvm.ssub.with.overflow.i64";
742 return "llvm.usub.with.overflow.i64";
744 return "llvm.smul.with.overflow.i64";
746 return "llvm.umul.with.overflow.i64";
748 g_assert_not_reached ();
754 simd_op_to_intrins (int opcode)
757 #if defined(TARGET_X86) || defined(TARGET_AMD64)
759 return "llvm.x86.sse2.min.pd";
761 return "llvm.x86.sse.min.ps";
763 return "llvm.x86.sse41.pminud";
765 return "llvm.x86.sse41.pminuw";
767 return "llvm.x86.sse2.pminu.b";
769 return "llvm.x86.sse2.pmins.w";
771 return "llvm.x86.sse2.max.pd";
773 return "llvm.x86.sse.max.ps";
775 return "llvm.x86.sse3.hadd.pd";
777 return "llvm.x86.sse3.hadd.ps";
779 return "llvm.x86.sse3.hsub.pd";
781 return "llvm.x86.sse3.hsub.ps";
783 return "llvm.x86.sse41.pmaxud";
785 return "llvm.x86.sse41.pmaxuw";
787 return "llvm.x86.sse2.pmaxu.b";
789 return "llvm.x86.sse3.addsub.ps";
791 return "llvm.x86.sse3.addsub.pd";
792 case OP_EXTRACT_MASK:
793 return "llvm.x86.sse2.pmovmskb.128";
796 return "llvm.x86.sse2.psrli.w";
799 return "llvm.x86.sse2.psrli.d";
802 return "llvm.x86.sse2.psrli.q";
805 return "llvm.x86.sse2.pslli.w";
808 return "llvm.x86.sse2.pslli.d";
811 return "llvm.x86.sse2.pslli.q";
814 return "llvm.x86.sse2.psrai.w";
817 return "llvm.x86.sse2.psrai.d";
819 return "llvm.x86.sse2.padds.b";
821 return "llvm.x86.sse2.padds.w";
823 return "llvm.x86.sse2.psubs.b";
825 return "llvm.x86.sse2.psubs.w";
826 case OP_PADDB_SAT_UN:
827 return "llvm.x86.sse2.paddus.b";
828 case OP_PADDW_SAT_UN:
829 return "llvm.x86.sse2.paddus.w";
830 case OP_PSUBB_SAT_UN:
831 return "llvm.x86.sse2.psubus.b";
832 case OP_PSUBW_SAT_UN:
833 return "llvm.x86.sse2.psubus.w";
835 return "llvm.x86.sse2.pavg.b";
837 return "llvm.x86.sse2.pavg.w";
839 return "llvm.x86.sse.sqrt.ps";
841 return "llvm.x86.sse2.sqrt.pd";
843 return "llvm.x86.sse.rsqrt.ps";
845 return "llvm.x86.sse.rcp.ps";
847 return "llvm.x86.sse2.cvtdq2pd";
849 return "llvm.x86.sse2.cvtdq2ps";
851 return "llvm.x86.sse2.cvtpd2dq";
853 return "llvm.x86.sse2.cvtps2dq";
855 return "llvm.x86.sse2.cvtpd2ps";
857 return "llvm.x86.sse2.cvtps2pd";
859 return "llvm.x86.sse2.cvttpd2dq";
861 return "llvm.x86.sse2.cvttps2dq";
863 return "llvm.x86.sse.cmp.ps";
865 return "llvm.x86.sse2.cmp.pd";
867 return "llvm.x86.sse2.packsswb.128";
869 return "llvm.x86.sse2.packssdw.128";
871 return "llvm.x86.sse2.packuswb.128";
873 return "llvm.x86.sse41.packusdw";
875 return "llvm.x86.sse2.pmulh.w";
876 case OP_PMULW_HIGH_UN:
877 return "llvm.x86.sse2.pmulhu.w";
880 g_assert_not_reached ();
886 simd_op_to_llvm_type (int opcode)
888 #if defined(TARGET_X86) || defined(TARGET_AMD64)
892 return type_to_simd_type (MONO_TYPE_R8);
895 return type_to_simd_type (MONO_TYPE_I8);
898 return type_to_simd_type (MONO_TYPE_I4);
903 return type_to_simd_type (MONO_TYPE_I2);
907 return type_to_simd_type (MONO_TYPE_I1);
909 return type_to_simd_type (MONO_TYPE_R4);
912 return type_to_simd_type (MONO_TYPE_I4);
916 return type_to_simd_type (MONO_TYPE_R8);
920 return type_to_simd_type (MONO_TYPE_R4);
921 case OP_EXTRACT_MASK:
922 return type_to_simd_type (MONO_TYPE_I1);
928 return type_to_simd_type (MONO_TYPE_R4);
931 return type_to_simd_type (MONO_TYPE_R8);
933 g_assert_not_reached ();
944 * Return the LLVM basic block corresponding to BB.
946 static LLVMBasicBlockRef
947 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
949 char bb_name_buf [128];
952 if (ctx->bblocks [bb->block_num].bblock == NULL) {
953 if (bb->flags & BB_EXCEPTION_HANDLER) {
954 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
955 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
956 bb_name = bb_name_buf;
957 } else if (bb->block_num < 256) {
958 if (!ctx->lmodule->bb_names) {
959 ctx->lmodule->bb_names_len = 256;
960 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
962 if (!ctx->lmodule->bb_names [bb->block_num]) {
965 n = g_strdup_printf ("BB%d", bb->block_num);
966 mono_memory_barrier ();
967 ctx->lmodule->bb_names [bb->block_num] = n;
969 bb_name = ctx->lmodule->bb_names [bb->block_num];
971 sprintf (bb_name_buf, "BB%d", bb->block_num);
972 bb_name = bb_name_buf;
975 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
976 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
979 return ctx->bblocks [bb->block_num].bblock;
985 * Return the last LLVM bblock corresponding to BB.
986 * This might not be equal to the bb returned by get_bb () since we need to generate
987 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
989 static LLVMBasicBlockRef
990 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
993 return ctx->bblocks [bb->block_num].end_bblock;
996 static LLVMBasicBlockRef
997 gen_bb (EmitContext *ctx, const char *prefix)
1001 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1002 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1008 * Return the target of the patch identified by TYPE and TARGET.
1011 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1015 memset (&ji, 0, sizeof (ji));
1017 ji.data.target = target;
1019 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1025 * Emit code to convert the LLVM value V to DTYPE.
1028 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1030 LLVMTypeRef stype = LLVMTypeOf (v);
1032 if (stype != dtype) {
1033 gboolean ext = FALSE;
1036 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1038 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1040 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1044 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1046 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1047 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1050 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1051 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1052 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1053 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1054 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1055 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1056 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1057 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1059 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1060 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1061 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1062 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1063 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1064 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1066 if (mono_arch_is_soft_float ()) {
1067 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1068 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1069 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1070 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1073 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1074 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1077 LLVMDumpValue (LLVMConstNull (dtype));
1078 g_assert_not_reached ();
1086 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1088 return convert_full (ctx, v, dtype, FALSE);
1092 * emit_volatile_load:
1094 * If vreg is volatile, emit a load from its address.
1097 emit_volatile_load (EmitContext *ctx, int vreg)
1101 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1102 t = ctx->vreg_cli_types [vreg];
1103 if (t && !t->byref) {
1105 * Might have to zero extend since llvm doesn't have
1108 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1109 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1110 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1111 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1112 else if (t->type == MONO_TYPE_U8)
1113 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1120 * emit_volatile_store:
1122 * If VREG is volatile, emit a store from its value to its address.
1125 emit_volatile_store (EmitContext *ctx, int vreg)
1127 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1129 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1130 g_assert (ctx->addresses [vreg]);
1131 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1137 * Maps parameter indexes in the original signature to parameter indexes
1138 * in the LLVM signature.
1141 /* The indexes of various special arguments in the LLVM signature */
1142 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1146 * sig_to_llvm_sig_full:
1148 * Return the LLVM signature corresponding to the mono signature SIG using the
1149 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1152 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1155 LLVMTypeRef ret_type;
1156 LLVMTypeRef *param_types = NULL;
1158 int i, j, pindex, vret_arg_pindex = 0;
1160 gboolean vretaddr = FALSE;
1164 memset (sinfo, 0, sizeof (LLVMSigInfo));
1166 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1167 ret_type = type_to_llvm_type (ctx, rtype);
1168 CHECK_FAILURE (ctx);
1171 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1172 /* LLVM models this by returning an aggregate value */
1173 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1174 LLVMTypeRef members [2];
1176 members [0] = IntPtrType ();
1177 ret_type = LLVMStructType (members, 1, FALSE);
1179 g_assert_not_reached ();
1181 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1182 /* Vtype returned normally by val */
1183 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1184 /* Vtype returned as a fp struct */
1185 LLVMTypeRef members [16];
1187 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1188 for (i = 0; i < cinfo->ret.nslots; ++i)
1189 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1190 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1191 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1192 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1194 ret_type = LLVMVoidType ();
1198 pindexes = g_new0 (int, sig->param_count);
1199 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1201 if (cinfo && cinfo->rgctx_arg) {
1203 sinfo->rgctx_arg_pindex = pindex;
1204 param_types [pindex] = ctx->lmodule->ptr_type;
1207 if (cinfo && cinfo->imt_arg) {
1209 sinfo->imt_arg_pindex = pindex;
1210 param_types [pindex] = ctx->lmodule->ptr_type;
1214 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1215 vret_arg_pindex = pindex;
1216 if (cinfo->vret_arg_index == 1) {
1217 /* Add the slots consumed by the first argument */
1218 LLVMArgInfo *ainfo = &cinfo->args [0];
1219 switch (ainfo->storage) {
1220 case LLVMArgVtypeInReg:
1221 for (j = 0; j < 2; ++j) {
1222 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1232 sinfo->vret_arg_pindex = vret_arg_pindex;
1235 if (vretaddr && vret_arg_pindex == pindex)
1236 param_types [pindex ++] = IntPtrType ();
1239 sinfo->this_arg_pindex = pindex;
1240 param_types [pindex ++] = ThisType ();
1242 if (vretaddr && vret_arg_pindex == pindex)
1243 param_types [pindex ++] = IntPtrType ();
1244 for (i = 0; i < sig->param_count; ++i) {
1245 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1247 if (vretaddr && vret_arg_pindex == pindex)
1248 param_types [pindex ++] = IntPtrType ();
1249 pindexes [i] = pindex;
1252 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1256 switch (ainfo->storage) {
1257 case LLVMArgVtypeInReg:
1258 for (j = 0; j < 2; ++j) {
1259 switch (ainfo->pair_storage [j]) {
1261 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1266 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1272 CHECK_FAILURE (ctx);
1273 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1276 case LLVMArgAsIArgs:
1277 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1280 case LLVMArgAsFpArgs: {
1283 for (j = 0; j < ainfo->nslots; ++j)
1284 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1285 pindex += ainfo->nslots;
1289 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1293 if (vretaddr && vret_arg_pindex == pindex)
1294 param_types [pindex ++] = IntPtrType ();
1296 CHECK_FAILURE (ctx);
1298 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1299 g_free (param_types);
1302 sinfo->pindexes = pindexes;
1310 g_free (param_types);
1316 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1318 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1322 * LLVMFunctionType1:
1324 * Create an LLVM function type from the arguments.
1326 static G_GNUC_UNUSED LLVMTypeRef
1327 LLVMFunctionType1(LLVMTypeRef ReturnType,
1328 LLVMTypeRef ParamType1,
1331 LLVMTypeRef param_types [1];
1333 param_types [0] = ParamType1;
1335 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1339 * LLVMFunctionType2:
1341 * Create an LLVM function type from the arguments.
1343 static G_GNUC_UNUSED LLVMTypeRef
1344 LLVMFunctionType2(LLVMTypeRef ReturnType,
1345 LLVMTypeRef ParamType1,
1346 LLVMTypeRef ParamType2,
1349 LLVMTypeRef param_types [2];
1351 param_types [0] = ParamType1;
1352 param_types [1] = ParamType2;
1354 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1358 * LLVMFunctionType3:
1360 * Create an LLVM function type from the arguments.
1362 static G_GNUC_UNUSED LLVMTypeRef
1363 LLVMFunctionType3(LLVMTypeRef ReturnType,
1364 LLVMTypeRef ParamType1,
1365 LLVMTypeRef ParamType2,
1366 LLVMTypeRef ParamType3,
1369 LLVMTypeRef param_types [3];
1371 param_types [0] = ParamType1;
1372 param_types [1] = ParamType2;
1373 param_types [2] = ParamType3;
1375 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1381 * Create an LLVM builder and remember it so it can be freed later.
1383 static LLVMBuilderRef
1384 create_builder (EmitContext *ctx)
1386 LLVMBuilderRef builder = LLVMCreateBuilder ();
1388 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1394 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1396 char *callee_name = mono_aot_get_plt_symbol (type, data);
1397 LLVMValueRef callee;
1398 MonoJumpInfo *ji = NULL;
1403 if (ctx->cfg->compile_aot)
1404 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1405 mono_add_patch_info (ctx->cfg, 0, type, data);
1408 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1410 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1412 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1414 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1417 if (ctx->cfg->compile_aot) {
1418 ji = g_new0 (MonoJumpInfo, 1);
1420 ji->data.target = data;
1422 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1429 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1431 MonoMethodHeader *header = cfg->header;
1432 MonoExceptionClause *clause;
1436 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1437 return (bb->region >> 8) - 1;
1440 for (i = 0; i < header->num_clauses; ++i) {
1441 clause = &header->clauses [i];
1443 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1451 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1453 LLVMValueRef md_arg;
1456 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1457 md_arg = LLVMMDString ("mono", 4);
1458 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1462 set_invariant_load_flag (LLVMValueRef v)
1464 LLVMValueRef md_arg;
1466 const char *flag_name;
1468 // FIXME: Cache this
1469 flag_name = "invariant.load";
1470 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1471 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1472 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1478 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1482 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1484 MonoCompile *cfg = ctx->cfg;
1486 LLVMBuilderRef builder = *builder_ref;
1489 clause_index = get_handler_clause (cfg, bb);
1491 if (clause_index != -1) {
1492 MonoMethodHeader *header = cfg->header;
1493 MonoExceptionClause *ec = &header->clauses [clause_index];
1494 MonoBasicBlock *tblock;
1495 LLVMBasicBlockRef ex_bb, noex_bb;
1498 * Have to use an invoke instead of a call, branching to the
1499 * handler bblock of the clause containing this bblock.
1502 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1504 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1507 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1509 ex_bb = get_bb (ctx, tblock);
1511 noex_bb = gen_bb (ctx, "NOEX_BB");
1514 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1516 builder = ctx->builder = create_builder (ctx);
1517 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1519 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1521 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1522 ctx->builder = builder;
1525 *builder_ref = ctx->builder;
1531 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1533 const char *intrins_name;
1534 LLVMValueRef args [16], res;
1535 LLVMTypeRef addr_type;
1537 if (is_faulting && bb->region != -1) {
1538 LLVMAtomicOrdering ordering;
1541 case LLVM_BARRIER_NONE:
1542 ordering = LLVMAtomicOrderingNotAtomic;
1544 case LLVM_BARRIER_ACQ:
1545 ordering = LLVMAtomicOrderingAcquire;
1547 case LLVM_BARRIER_SEQ:
1548 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1551 g_assert_not_reached ();
1556 * We handle loads which can fault by calling a mono specific intrinsic
1557 * using an invoke, so they are handled properly inside try blocks.
1558 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1559 * are marked with IntrReadArgMem.
1563 intrins_name = "llvm.mono.load.i8.p0i8";
1566 intrins_name = "llvm.mono.load.i16.p0i16";
1569 intrins_name = "llvm.mono.load.i32.p0i32";
1572 intrins_name = "llvm.mono.load.i64.p0i64";
1575 g_assert_not_reached ();
1578 addr_type = LLVMTypeOf (addr);
1579 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1580 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1583 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1584 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1585 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1586 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1588 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1589 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1590 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1591 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1598 * We emit volatile loads for loads which can fault, because otherwise
1599 * LLVM will generate invalid code when encountering a load from a
1602 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1604 /* Mark it with a custom metadata */
1607 set_metadata_flag (res, "mono.faulting.load");
1615 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1617 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1621 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1623 const char *intrins_name;
1624 LLVMValueRef args [16];
1626 if (is_faulting && bb->region != -1) {
1627 LLVMAtomicOrdering ordering;
1630 case LLVM_BARRIER_NONE:
1631 ordering = LLVMAtomicOrderingNotAtomic;
1633 case LLVM_BARRIER_REL:
1634 ordering = LLVMAtomicOrderingRelease;
1636 case LLVM_BARRIER_SEQ:
1637 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1640 g_assert_not_reached ();
1646 intrins_name = "llvm.mono.store.i8.p0i8";
1649 intrins_name = "llvm.mono.store.i16.p0i16";
1652 intrins_name = "llvm.mono.store.i32.p0i32";
1655 intrins_name = "llvm.mono.store.i64.p0i64";
1658 g_assert_not_reached ();
1661 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1662 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1663 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1668 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1669 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1670 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1671 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1673 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1678 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1680 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1684 * emit_cond_system_exception:
1686 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1687 * Might set the ctx exception.
1690 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1692 LLVMBasicBlockRef ex_bb, noex_bb;
1693 LLVMBuilderRef builder;
1694 MonoClass *exc_class;
1695 LLVMValueRef args [2];
1697 ex_bb = gen_bb (ctx, "EX_BB");
1698 noex_bb = gen_bb (ctx, "NOEX_BB");
1700 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1702 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1703 g_assert (exc_class);
1705 /* Emit exception throwing code */
1706 builder = create_builder (ctx);
1707 LLVMPositionBuilderAtEnd (builder, ex_bb);
1709 if (!ctx->lmodule->throw_corlib_exception) {
1710 LLVMValueRef callee;
1712 const char *icall_name;
1714 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1715 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1716 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1717 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1718 /* This will become i8* */
1719 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1720 sig = sig_to_llvm_sig (ctx, throw_sig);
1722 if (ctx->cfg->compile_aot) {
1723 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1725 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1728 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1729 * - On x86, LLVM generated code doesn't push the arguments
1730 * - The trampoline takes the throw address as an arguments, not a pc offset.
1732 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1735 mono_memory_barrier ();
1736 ctx->lmodule->throw_corlib_exception = callee;
1739 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1740 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1742 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1745 * The LLVM mono branch contains changes so a block address can be passed as an
1746 * argument to a call.
1748 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1749 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1751 LLVMBuildUnreachable (builder);
1753 ctx->builder = create_builder (ctx);
1754 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1756 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1763 * emit_args_to_vtype:
1765 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1768 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1770 int j, size, nslots;
1772 size = get_vtype_size (t);
1774 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1775 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1778 if (ainfo->storage == LLVMArgAsFpArgs)
1779 nslots = ainfo->nslots;
1783 for (j = 0; j < nslots; ++j) {
1784 LLVMValueRef index [2], addr, daddr;
1785 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1786 LLVMTypeRef part_type;
1788 if (ainfo->pair_storage [j] == LLVMArgNone)
1791 switch (ainfo->pair_storage [j]) {
1792 case LLVMArgInIReg: {
1793 part_type = LLVMIntType (part_size * 8);
1794 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1795 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1796 addr = LLVMBuildGEP (builder, address, index, 1, "");
1798 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1799 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1800 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1802 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1805 case LLVMArgInFPReg: {
1806 LLVMTypeRef arg_type;
1808 if (ainfo->esize == 8)
1809 arg_type = LLVMDoubleType ();
1811 arg_type = LLVMFloatType ();
1813 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1814 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1815 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1816 LLVMBuildStore (builder, args [j], addr);
1822 g_assert_not_reached ();
1825 size -= sizeof (gpointer);
1830 * emit_vtype_to_args:
1832 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1833 * into ARGS, and the number of arguments into NARGS.
1836 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1839 int j, size, nslots;
1840 LLVMTypeRef arg_type;
1842 size = get_vtype_size (t);
1844 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1845 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1847 if (ainfo->storage == LLVMArgAsFpArgs)
1848 nslots = ainfo->nslots;
1851 for (j = 0; j < nslots; ++j) {
1852 LLVMValueRef index [2], addr, daddr;
1853 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1855 if (ainfo->pair_storage [j] == LLVMArgNone)
1858 switch (ainfo->pair_storage [j]) {
1860 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1861 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1862 addr = LLVMBuildGEP (builder, address, index, 1, "");
1864 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1865 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1866 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1868 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1870 case LLVMArgInFPReg:
1871 if (ainfo->esize == 8)
1872 arg_type = LLVMDoubleType ();
1874 arg_type = LLVMFloatType ();
1875 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1876 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1877 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1878 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1883 g_assert_not_reached ();
1885 size -= sizeof (gpointer);
1892 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1895 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1896 * get executed every time control reaches them.
1898 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1900 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1901 return ctx->last_alloca;
1905 build_alloca (EmitContext *ctx, MonoType *t)
1907 MonoClass *k = mono_class_from_mono_type (t);
1910 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1913 align = mono_class_min_align (k);
1915 /* Sometimes align is not a power of 2 */
1916 while (mono_is_power_of_two (align) == -1)
1919 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1923 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1926 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1929 lmodule->used = g_ptr_array_sized_new (16);
1930 g_ptr_array_add (lmodule->used, global);
1934 emit_llvm_used (MonoLLVMModule *lmodule)
1936 LLVMModuleRef module = lmodule->module;
1937 LLVMTypeRef used_type;
1938 LLVMValueRef used, *used_elem;
1944 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1945 used = LLVMAddGlobal (module, used_type, "llvm.used");
1946 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1947 for (i = 0; i < lmodule->used->len; ++i)
1948 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1949 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1950 LLVMSetLinkage (used, LLVMAppendingLinkage);
1951 LLVMSetSection (used, "llvm.metadata");
1955 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1957 gboolean need_div_check = FALSE;
1959 #ifdef MONO_ARCH_NEED_DIV_CHECK
1960 need_div_check = TRUE;
1963 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1964 need_div_check = TRUE;
1966 if (!need_div_check)
1969 switch (ins->opcode) {
1982 case OP_IDIV_UN_IMM:
1983 case OP_LDIV_UN_IMM:
1984 case OP_IREM_UN_IMM:
1985 case OP_LREM_UN_IMM: {
1987 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1988 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
1990 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
1991 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
1992 CHECK_FAILURE (ctx);
1993 builder = ctx->builder;
1995 /* b == -1 && a == 0x80000000 */
1997 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
1998 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
1999 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2001 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2002 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2003 CHECK_FAILURE (ctx);
2004 builder = ctx->builder;
2019 * Emit code to load/convert arguments.
2022 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2025 MonoCompile *cfg = ctx->cfg;
2026 MonoMethodSignature *sig = ctx->sig;
2027 LLVMCallInfo *linfo = ctx->linfo;
2030 ctx->alloca_builder = create_builder (ctx);
2033 * Handle indirect/volatile variables by allocating memory for them
2034 * using 'alloca', and storing their address in a temporary.
2036 for (i = 0; i < cfg->num_varinfo; ++i) {
2037 MonoInst *var = cfg->varinfo [i];
2040 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2041 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2042 CHECK_FAILURE (ctx);
2043 /* Could be already created by an OP_VPHI */
2044 if (!ctx->addresses [var->dreg])
2045 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2046 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2050 for (i = 0; i < sig->param_count; ++i) {
2051 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2052 int reg = cfg->args [i + sig->hasthis]->dreg;
2054 switch (ainfo->storage) {
2055 case LLVMArgVtypeInReg:
2056 case LLVMArgAsFpArgs: {
2057 LLVMValueRef args [8];
2060 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2061 memset (args, 0, sizeof (args));
2062 pindex = ctx->pindexes [i];
2063 if (ainfo->storage == LLVMArgVtypeInReg) {
2064 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2065 if (ainfo->pair_storage [1] != LLVMArgNone)
2066 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2068 g_assert (ainfo->nslots <= 8);
2069 for (j = 0; j < ainfo->nslots; ++j)
2070 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2072 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2074 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2076 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2077 /* Treat these as normal values */
2078 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2082 case LLVMArgVtypeByVal: {
2083 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2085 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2086 /* Treat these as normal values */
2087 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2091 case LLVMArgAsIArgs: {
2092 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2094 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2096 /* The argument is received as an array of ints, store it into the real argument */
2097 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2101 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->params [i])), type_is_unsigned (ctx, sig->params [i]));
2107 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2109 emit_volatile_store (ctx, cfg->args [0]->dreg);
2110 for (i = 0; i < sig->param_count; ++i)
2111 if (!mini_type_is_vtype (cfg, sig->params [i]))
2112 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2114 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2115 LLVMValueRef this_alloc;
2118 * The exception handling code needs the location where the this argument was
2119 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2120 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2121 * location into the LSDA.
2123 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2124 /* This volatile store will keep the alloca alive */
2125 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2127 set_metadata_flag (this_alloc, "mono.this");
2130 if (cfg->rgctx_var) {
2131 LLVMValueRef rgctx_alloc, store;
2134 * We handle the rgctx arg similarly to the this pointer.
2136 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2137 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2138 /* This volatile store will keep the alloca alive */
2139 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2141 set_metadata_flag (rgctx_alloc, "mono.this");
2144 /* Compute nesting between clauses */
2145 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2146 for (i = 0; i < cfg->header->num_clauses; ++i) {
2147 for (j = 0; j < cfg->header->num_clauses; ++j) {
2148 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2149 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2151 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2152 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2157 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2158 * it needs to continue normally, or return back to the exception handling system.
2160 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2164 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2167 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2168 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2169 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2171 if (bb->in_scount == 0) {
2174 sprintf (name, "finally_ind_bb%d", bb->block_num);
2175 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2176 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2178 ctx->bblocks [bb->block_num].finally_ind = val;
2180 /* Create a variable to hold the exception var */
2182 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2186 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2187 * LLVM bblock containing a landing pad causes problems for the
2188 * LLVM optimizer passes.
2190 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2191 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2198 /* Have to export this for AOT */
2200 mono_personality (void)
2203 g_assert_not_reached ();
2207 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2209 MonoCompile *cfg = ctx->cfg;
2210 LLVMModuleRef module = ctx->module;
2211 LLVMValueRef *values = ctx->values;
2212 LLVMValueRef *addresses = ctx->addresses;
2213 MonoCallInst *call = (MonoCallInst*)ins;
2214 MonoMethodSignature *sig = call->signature;
2215 LLVMValueRef callee = NULL, lcall;
2217 LLVMCallInfo *cinfo;
2221 LLVMTypeRef llvm_sig;
2223 gboolean virtual, calli;
2224 LLVMBuilderRef builder = *builder_ref;
2227 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2228 LLVM_FAILURE (ctx, "non-default callconv");
2230 cinfo = call->cinfo;
2231 if (call->rgctx_arg_reg)
2232 cinfo->rgctx_arg = TRUE;
2233 if (call->imt_arg_reg)
2234 cinfo->imt_arg = TRUE;
2236 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2238 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2239 CHECK_FAILURE (ctx);
2241 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);
2242 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);
2244 /* FIXME: Avoid creating duplicate methods */
2246 if (ins->flags & MONO_INST_HAS_METHOD) {
2250 if (cfg->compile_aot) {
2251 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2253 LLVM_FAILURE (ctx, "can't encode patch");
2255 callee = LLVMAddFunction (module, "", llvm_sig);
2258 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2260 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2264 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2265 /* LLVM miscompiles async methods */
2266 LLVM_FAILURE (ctx, "#13734");
2269 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2275 memset (&ji, 0, sizeof (ji));
2276 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2277 ji.data.target = info->name;
2279 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2281 if (cfg->compile_aot) {
2282 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2284 LLVM_FAILURE (ctx, "can't encode patch");
2286 callee = LLVMAddFunction (module, "", llvm_sig);
2287 target = (gpointer)mono_icall_get_wrapper (info);
2288 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2291 if (cfg->compile_aot) {
2293 if (cfg->abs_patches) {
2294 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2296 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2298 LLVM_FAILURE (ctx, "can't encode patch");
2302 LLVM_FAILURE (ctx, "aot");
2304 callee = LLVMAddFunction (module, "", llvm_sig);
2306 if (cfg->abs_patches) {
2307 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2310 * FIXME: Some trampolines might have
2311 * their own calling convention on some platforms.
2313 #ifndef TARGET_AMD64
2314 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2315 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
2316 LLVM_FAILURE (ctx, "trampoline with own cconv");
2318 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2319 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2323 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2329 int size = sizeof (gpointer);
2332 g_assert (ins->inst_offset % size == 0);
2333 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2335 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2337 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2339 if (ins->flags & MONO_INST_HAS_METHOD) {
2344 * Collect and convert arguments
2346 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2347 len = sizeof (LLVMValueRef) * nargs;
2348 args = alloca (len);
2349 memset (args, 0, len);
2350 l = call->out_ireg_args;
2352 if (call->rgctx_arg_reg) {
2353 g_assert (values [call->rgctx_arg_reg]);
2354 g_assert (sinfo.rgctx_arg_pindex < nargs);
2356 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2357 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2358 * it using a volatile load.
2361 if (!ctx->imt_rgctx_loc)
2362 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2363 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2364 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2366 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2369 if (call->imt_arg_reg) {
2370 g_assert (values [call->imt_arg_reg]);
2371 g_assert (sinfo.imt_arg_pindex < nargs);
2373 if (!ctx->imt_rgctx_loc)
2374 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2375 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2376 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2378 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2383 if (!addresses [call->inst.dreg])
2384 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2385 g_assert (sinfo.vret_arg_pindex < nargs);
2386 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2389 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2392 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2396 pindex = sinfo.this_arg_pindex;
2398 pindex = sinfo.pindexes [i - 1];
2400 pindex = sinfo.pindexes [i];
2403 regpair = (guint32)(gssize)(l->data);
2404 reg = regpair & 0xffffff;
2405 args [pindex] = values [reg];
2406 switch (ainfo->storage) {
2407 case LLVMArgVtypeInReg:
2408 case LLVMArgAsFpArgs: {
2411 g_assert (addresses [reg]);
2412 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2416 // FIXME: Get rid of the VMOVE
2419 case LLVMArgVtypeByVal:
2420 g_assert (addresses [reg]);
2421 args [pindex] = addresses [reg];
2423 case LLVMArgAsIArgs:
2424 g_assert (addresses [reg]);
2425 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2428 g_assert (args [pindex]);
2429 if (i == 0 && sig->hasthis)
2430 args [pindex] = convert (ctx, args [pindex], ThisType ());
2432 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2435 g_assert (pindex <= nargs);
2440 // FIXME: Align call sites
2446 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2449 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2451 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2452 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2454 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2455 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2457 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2459 if (call->rgctx_arg_reg)
2460 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2461 if (call->imt_arg_reg)
2462 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2464 /* Add byval attributes if needed */
2465 for (i = 0; i < sig->param_count; ++i) {
2466 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2468 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2469 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2474 * Convert the result
2477 switch (cinfo->ret.storage) {
2478 case LLVMArgVtypeInReg: {
2479 LLVMValueRef regs [2];
2481 if (!addresses [ins->dreg])
2482 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2484 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2485 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2486 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2487 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2490 case LLVMArgVtypeByVal:
2491 if (!addresses [call->inst.dreg])
2492 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2493 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2495 case LLVMArgFpStruct:
2496 if (!addresses [call->inst.dreg])
2497 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2498 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2501 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2502 /* If the method returns an unsigned value, need to zext it */
2503 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));
2507 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2508 /* If the method returns an unsigned value, need to zext it */
2509 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));
2513 if (!addresses [call->inst.dreg])
2514 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2515 g_assert (sinfo.vret_arg_pindex < nargs);
2516 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2519 *builder_ref = ctx->builder;
2521 g_free (sinfo.pindexes);
2529 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2531 MonoCompile *cfg = ctx->cfg;
2532 LLVMValueRef *values = ctx->values;
2533 LLVMModuleRef module = ctx->module;
2534 BBInfo *bblocks = ctx->bblocks;
2536 LLVMValueRef personality;
2537 LLVMValueRef landing_pad;
2538 LLVMBasicBlockRef target_bb;
2540 static gint32 mapping_inited;
2541 static int ti_generator;
2544 LLVMValueRef type_info;
2548 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2550 if (cfg->compile_aot) {
2551 /* Use a dummy personality function */
2552 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2553 g_assert (personality);
2555 personality = LLVMGetNamedFunction (module, "mono_personality");
2556 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2557 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2560 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2562 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2565 * Create the type info
2567 sprintf (ti_name, "type_info_%d", ti_generator);
2570 if (cfg->compile_aot) {
2571 /* decode_eh_frame () in aot-runtime.c will decode this */
2572 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2573 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2576 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2578 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2581 * After the cfg mempool is freed, the type info will point to stale memory,
2582 * but this is not a problem, since we decode it once in exception_cb during
2585 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2586 *(gint32*)ti = clause_index;
2588 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2590 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2594 LLVMTypeRef members [2], ret_type;
2596 members [0] = i8ptr;
2597 members [1] = LLVMInt32Type ();
2598 ret_type = LLVMStructType (members, 2, FALSE);
2600 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2601 LLVMAddClause (landing_pad, type_info);
2603 /* Store the exception into the exvar */
2605 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2609 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2610 * code expects control to be transferred to this landing pad even in the
2611 * presence of nested clauses. The landing pad needs to branch to the landing
2612 * pads belonging to nested clauses based on the selector value returned by
2613 * the landing pad instruction, which is passed to the landing pad in a
2614 * register by the EH code.
2616 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2617 g_assert (target_bb);
2620 * Branch to the correct landing pad
2622 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2623 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2625 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2626 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2627 MonoBasicBlock *handler_bb;
2629 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2630 g_assert (handler_bb);
2632 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2633 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2636 /* Start a new bblock which CALL_HANDLER can branch to */
2637 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2639 ctx->builder = builder = create_builder (ctx);
2640 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2642 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2644 /* Store the exception into the IL level exvar */
2645 if (bb->in_scount == 1) {
2646 g_assert (bb->in_scount == 1);
2647 exvar = bb->in_stack [0];
2649 // FIXME: This is shared with filter clauses ?
2650 g_assert (!values [exvar->dreg]);
2652 g_assert (ctx->ex_var);
2653 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2654 emit_volatile_store (ctx, exvar->dreg);
2660 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2662 MonoCompile *cfg = ctx->cfg;
2663 MonoMethodSignature *sig = ctx->sig;
2664 LLVMValueRef method = ctx->lmethod;
2665 LLVMValueRef *values = ctx->values;
2666 LLVMValueRef *addresses = ctx->addresses;
2667 LLVMCallInfo *linfo = ctx->linfo;
2668 LLVMModuleRef module = ctx->module;
2669 BBInfo *bblocks = ctx->bblocks;
2671 LLVMBasicBlockRef cbb;
2672 LLVMBuilderRef builder, starting_builder;
2673 gboolean has_terminator;
2675 LLVMValueRef lhs, rhs;
2678 cbb = get_bb (ctx, bb);
2679 builder = create_builder (ctx);
2680 ctx->builder = builder;
2681 LLVMPositionBuilderAtEnd (builder, cbb);
2683 if (bb == cfg->bb_entry)
2684 emit_entry_bb (ctx, builder);
2685 CHECK_FAILURE (ctx);
2687 if (bb->flags & BB_EXCEPTION_HANDLER) {
2688 if (!bblocks [bb->block_num].invoke_target) {
2690 * LLVM asserts if llvm.eh.selector is called from a bblock which
2691 * doesn't have an invoke pointing at it.
2692 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2694 LLVM_FAILURE (ctx, "handler without invokes");
2697 emit_handler_start (ctx, bb, builder);
2698 CHECK_FAILURE (ctx);
2699 builder = ctx->builder;
2702 has_terminator = FALSE;
2703 starting_builder = builder;
2704 for (ins = bb->code; ins; ins = ins->next) {
2705 const char *spec = LLVM_INS_INFO (ins->opcode);
2707 char dname_buf [128];
2709 emit_dbg_loc (ctx, builder, ins->cil_code);
2712 if (nins > 5000 && builder == starting_builder) {
2713 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2714 LLVM_FAILURE (ctx, "basic block too long");
2718 /* There could be instructions after a terminator, skip them */
2721 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2722 sprintf (dname_buf, "t%d", ins->dreg);
2726 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2727 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2729 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2730 lhs = emit_volatile_load (ctx, ins->sreg1);
2732 /* It is ok for SETRET to have an uninitialized argument */
2733 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2734 LLVM_FAILURE (ctx, "sreg1");
2735 lhs = values [ins->sreg1];
2741 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2742 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2743 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2744 rhs = emit_volatile_load (ctx, ins->sreg2);
2746 if (!values [ins->sreg2])
2747 LLVM_FAILURE (ctx, "sreg2");
2748 rhs = values [ins->sreg2];
2754 //mono_print_ins (ins);
2755 switch (ins->opcode) {
2758 case OP_LIVERANGE_START:
2759 case OP_LIVERANGE_END:
2762 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2765 #if SIZEOF_VOID_P == 4
2766 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2768 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2772 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2776 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2778 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2780 case OP_DUMMY_ICONST:
2781 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2783 case OP_DUMMY_I8CONST:
2784 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2786 case OP_DUMMY_R8CONST:
2787 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2790 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2791 has_terminator = TRUE;
2797 LLVMBasicBlockRef new_bb;
2798 LLVMBuilderRef new_builder;
2800 // The default branch is already handled
2801 // FIXME: Handle it here
2803 /* Start new bblock */
2804 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2805 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2807 lhs = convert (ctx, lhs, LLVMInt32Type ());
2808 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2809 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2810 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2812 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2815 new_builder = create_builder (ctx);
2816 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2817 LLVMBuildUnreachable (new_builder);
2819 has_terminator = TRUE;
2820 g_assert (!ins->next);
2826 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2827 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2828 LLVMValueRef part1, retval;
2831 size = get_vtype_size (sig->ret);
2833 g_assert (addresses [ins->sreg1]);
2835 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2836 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2838 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2840 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2842 LLVMBuildRet (builder, retval);
2846 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2847 LLVMValueRef retval;
2849 g_assert (addresses [ins->sreg1]);
2850 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2851 LLVMBuildRet (builder, retval);
2855 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2856 LLVMBuildRetVoid (builder);
2860 if (linfo->ret.storage == LLVMArgFpStruct) {
2861 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2862 LLVMValueRef retval;
2864 g_assert (addresses [ins->sreg1]);
2865 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2866 LLVMBuildRet (builder, retval);
2870 if (!lhs || ctx->is_dead [ins->sreg1]) {
2872 * The method did not set its return value, probably because it
2873 * ends with a throw.
2876 LLVMBuildRetVoid (builder);
2878 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2880 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2882 has_terminator = TRUE;
2889 case OP_ICOMPARE_IMM:
2890 case OP_LCOMPARE_IMM:
2891 case OP_COMPARE_IMM: {
2895 if (ins->next->opcode == OP_NOP)
2898 if (ins->next->opcode == OP_BR)
2899 /* The comparison result is not needed */
2902 rel = mono_opcode_to_cond (ins->next->opcode);
2904 if (ins->opcode == OP_ICOMPARE_IMM) {
2905 lhs = convert (ctx, lhs, LLVMInt32Type ());
2906 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2908 if (ins->opcode == OP_LCOMPARE_IMM) {
2909 lhs = convert (ctx, lhs, LLVMInt64Type ());
2910 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2912 if (ins->opcode == OP_LCOMPARE) {
2913 lhs = convert (ctx, lhs, LLVMInt64Type ());
2914 rhs = convert (ctx, rhs, LLVMInt64Type ());
2916 if (ins->opcode == OP_ICOMPARE) {
2917 lhs = convert (ctx, lhs, LLVMInt32Type ());
2918 rhs = convert (ctx, rhs, LLVMInt32Type ());
2922 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2923 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2924 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2925 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2928 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2929 if (ins->opcode == OP_FCOMPARE) {
2930 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2931 } else if (ins->opcode == OP_RCOMPARE) {
2932 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2933 } else if (ins->opcode == OP_COMPARE_IMM) {
2934 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2935 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2937 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2938 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2939 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2940 /* The immediate is encoded in two fields */
2941 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2942 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2944 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2947 else if (ins->opcode == OP_COMPARE) {
2948 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2949 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2951 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2953 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2955 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2956 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2958 * If the target bb contains PHI instructions, LLVM requires
2959 * two PHI entries for this bblock, while we only generate one.
2960 * So convert this to an unconditional bblock. (bxc #171).
2962 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2964 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2966 has_terminator = TRUE;
2967 } else if (MONO_IS_SETCC (ins->next)) {
2968 sprintf (dname_buf, "t%d", ins->next->dreg);
2970 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2972 /* Add stores for volatile variables */
2973 emit_volatile_store (ctx, ins->next->dreg);
2974 } else if (MONO_IS_COND_EXC (ins->next)) {
2975 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2976 CHECK_FAILURE (ctx);
2977 builder = ctx->builder;
2979 LLVM_FAILURE (ctx, "next");
2993 rel = mono_opcode_to_cond (ins->opcode);
2995 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2996 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3007 rel = mono_opcode_to_cond (ins->opcode);
3009 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3010 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3018 gboolean empty = TRUE;
3020 /* Check that all input bblocks really branch to us */
3021 for (i = 0; i < bb->in_count; ++i) {
3022 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3023 ins->inst_phi_args [i + 1] = -1;
3029 /* LLVM doesn't like phi instructions with zero operands */
3030 ctx->is_dead [ins->dreg] = TRUE;
3034 /* Created earlier, insert it now */
3035 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3037 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3038 int sreg1 = ins->inst_phi_args [i + 1];
3042 * Count the number of times the incoming bblock branches to us,
3043 * since llvm requires a separate entry for each.
3045 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3046 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3049 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3050 if (switch_ins->inst_many_bb [j] == bb)
3057 /* Remember for later */
3058 for (j = 0; j < count; ++j) {
3059 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3062 node->in_bb = bb->in_bb [i];
3064 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);
3074 values [ins->dreg] = lhs;
3078 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3081 values [ins->dreg] = lhs;
3083 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3085 * This is added by the spilling pass in case of the JIT,
3086 * but we have to do it ourselves.
3088 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3092 case OP_MOVE_F_TO_I4: {
3093 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3096 case OP_MOVE_I4_TO_F: {
3097 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3100 case OP_MOVE_F_TO_I8: {
3101 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3104 case OP_MOVE_I8_TO_F: {
3105 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3138 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3139 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3141 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3142 CHECK_FAILURE (ctx);
3143 builder = ctx->builder;
3145 switch (ins->opcode) {
3148 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3152 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3156 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3160 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3164 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3168 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3172 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3176 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3180 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3184 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3188 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3192 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3196 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3200 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3204 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3207 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3210 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3214 g_assert_not_reached ();
3221 lhs = convert (ctx, lhs, LLVMFloatType ());
3222 rhs = convert (ctx, rhs, LLVMFloatType ());
3223 switch (ins->opcode) {
3225 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3228 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3231 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3234 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3237 g_assert_not_reached ();
3246 case OP_IREM_UN_IMM:
3248 case OP_IDIV_UN_IMM:
3254 case OP_ISHR_UN_IMM:
3263 case OP_LSHR_UN_IMM:
3269 case OP_SHR_UN_IMM: {
3272 if (spec [MONO_INST_SRC1] == 'l') {
3273 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3275 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3278 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3279 CHECK_FAILURE (ctx);
3280 builder = ctx->builder;
3282 #if SIZEOF_VOID_P == 4
3283 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3284 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3287 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3288 lhs = convert (ctx, lhs, IntPtrType ());
3289 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3290 switch (ins->opcode) {
3294 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3298 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3302 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3306 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3308 case OP_IDIV_UN_IMM:
3309 case OP_LDIV_UN_IMM:
3310 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3314 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3316 case OP_IREM_UN_IMM:
3317 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3322 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3326 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3330 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3335 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3340 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3342 case OP_ISHR_UN_IMM:
3343 /* This is used to implement conv.u4, so the lhs could be an i8 */
3344 lhs = convert (ctx, lhs, LLVMInt32Type ());
3345 imm = convert (ctx, imm, LLVMInt32Type ());
3346 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3348 case OP_LSHR_UN_IMM:
3350 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3353 g_assert_not_reached ();
3358 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3361 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3364 lhs = convert (ctx, lhs, LLVMDoubleType ());
3365 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3368 lhs = convert (ctx, lhs, LLVMFloatType ());
3369 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3372 guint32 v = 0xffffffff;
3373 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3377 guint64 v = 0xffffffffffffffffLL;
3378 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3381 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3383 LLVMValueRef v1, v2;
3385 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3386 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3387 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3392 case OP_ICONV_TO_I1:
3393 case OP_ICONV_TO_I2:
3394 case OP_ICONV_TO_I4:
3395 case OP_ICONV_TO_U1:
3396 case OP_ICONV_TO_U2:
3397 case OP_ICONV_TO_U4:
3398 case OP_LCONV_TO_I1:
3399 case OP_LCONV_TO_I2:
3400 case OP_LCONV_TO_U1:
3401 case OP_LCONV_TO_U2:
3402 case OP_LCONV_TO_U4: {
3405 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);
3407 /* Have to do two casts since our vregs have type int */
3408 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3410 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3412 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3415 case OP_ICONV_TO_I8:
3416 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3418 case OP_ICONV_TO_U8:
3419 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3421 case OP_FCONV_TO_I4:
3422 case OP_RCONV_TO_I4:
3423 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3425 case OP_FCONV_TO_I1:
3426 case OP_RCONV_TO_I1:
3427 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3429 case OP_FCONV_TO_U1:
3430 case OP_RCONV_TO_U1:
3431 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3433 case OP_FCONV_TO_I2:
3434 case OP_RCONV_TO_I2:
3435 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3437 case OP_FCONV_TO_U2:
3438 case OP_RCONV_TO_U2:
3439 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3441 case OP_FCONV_TO_I8:
3442 case OP_RCONV_TO_I8:
3443 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3446 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3448 case OP_ICONV_TO_R8:
3449 case OP_LCONV_TO_R8:
3450 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3452 case OP_LCONV_TO_R_UN:
3453 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3455 #if SIZEOF_VOID_P == 4
3458 case OP_LCONV_TO_I4:
3459 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3461 case OP_ICONV_TO_R4:
3462 case OP_LCONV_TO_R4:
3463 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3465 values [ins->dreg] = v;
3467 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3469 case OP_FCONV_TO_R4:
3470 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3472 values [ins->dreg] = v;
3474 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3476 case OP_RCONV_TO_R8:
3477 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3479 case OP_RCONV_TO_R4:
3480 values [ins->dreg] = lhs;
3483 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3486 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3489 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3491 case OP_LOCALLOC_IMM: {
3494 guint32 size = ins->inst_imm;
3495 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3497 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3499 if (ins->flags & MONO_INST_INIT) {
3500 LLVMValueRef args [5];
3503 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3504 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3505 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3506 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3507 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3510 values [ins->dreg] = v;
3514 LLVMValueRef v, size;
3516 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), "");
3518 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3520 if (ins->flags & MONO_INST_INIT) {
3521 LLVMValueRef args [5];
3524 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3526 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3527 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3528 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3530 values [ins->dreg] = v;
3534 case OP_LOADI1_MEMBASE:
3535 case OP_LOADU1_MEMBASE:
3536 case OP_LOADI2_MEMBASE:
3537 case OP_LOADU2_MEMBASE:
3538 case OP_LOADI4_MEMBASE:
3539 case OP_LOADU4_MEMBASE:
3540 case OP_LOADI8_MEMBASE:
3541 case OP_LOADR4_MEMBASE:
3542 case OP_LOADR8_MEMBASE:
3543 case OP_LOAD_MEMBASE:
3551 LLVMValueRef base, index, addr;
3553 gboolean sext = FALSE, zext = FALSE;
3554 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3556 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3561 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)) {
3562 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3567 if (ins->inst_offset == 0) {
3569 } else if (ins->inst_offset % size != 0) {
3570 /* Unaligned load */
3571 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3572 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3574 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3575 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3579 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3581 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3583 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3585 * These will signal LLVM that these loads do not alias any stores, and
3586 * they can't fail, allowing them to be hoisted out of loops.
3588 set_invariant_load_flag (values [ins->dreg]);
3589 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3593 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3595 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3596 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3597 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3601 case OP_STOREI1_MEMBASE_REG:
3602 case OP_STOREI2_MEMBASE_REG:
3603 case OP_STOREI4_MEMBASE_REG:
3604 case OP_STOREI8_MEMBASE_REG:
3605 case OP_STORER4_MEMBASE_REG:
3606 case OP_STORER8_MEMBASE_REG:
3607 case OP_STORE_MEMBASE_REG: {
3609 LLVMValueRef index, addr;
3611 gboolean sext = FALSE, zext = FALSE;
3612 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3614 if (!values [ins->inst_destbasereg])
3615 LLVM_FAILURE (ctx, "inst_destbasereg");
3617 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3619 if (ins->inst_offset % size != 0) {
3620 /* Unaligned store */
3621 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3622 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3624 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3625 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3627 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3631 case OP_STOREI1_MEMBASE_IMM:
3632 case OP_STOREI2_MEMBASE_IMM:
3633 case OP_STOREI4_MEMBASE_IMM:
3634 case OP_STOREI8_MEMBASE_IMM:
3635 case OP_STORE_MEMBASE_IMM: {
3637 LLVMValueRef index, addr;
3639 gboolean sext = FALSE, zext = FALSE;
3640 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3642 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3644 if (ins->inst_offset % size != 0) {
3645 /* Unaligned store */
3646 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3647 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3649 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3650 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3652 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3657 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3659 case OP_OUTARG_VTRETADDR:
3667 case OP_VOIDCALL_MEMBASE:
3668 case OP_CALL_MEMBASE:
3669 case OP_LCALL_MEMBASE:
3670 case OP_FCALL_MEMBASE:
3671 case OP_RCALL_MEMBASE:
3672 case OP_VCALL_MEMBASE:
3673 case OP_VOIDCALL_REG:
3678 case OP_VCALL_REG: {
3679 process_call (ctx, bb, &builder, ins);
3680 CHECK_FAILURE (ctx);
3683 case OP_GENERIC_CLASS_INIT: {
3684 static int byte_offset = -1;
3685 static guint8 bitmask;
3686 LLVMValueRef flags_load, cmp;
3687 MonoMethodSignature *sig;
3688 const char *icall_name;
3689 LLVMValueRef callee;
3690 LLVMBasicBlockRef init_bb, noinit_bb;
3691 LLVMValueRef args [16];
3693 if (byte_offset < 0)
3694 mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
3696 flags_load = emit_load (ctx, bb, &builder, 1, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type(), 0)), "", FALSE);
3697 set_metadata_flag (flags_load, "mono.nofail.load");
3698 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, flags_load, LLVMConstInt (LLVMInt8Type (), bitmask, 0), ""), LLVMConstInt (LLVMInt8Type (), 1, FALSE), "");
3700 callee = ctx->lmodule->generic_class_init_tramp;
3702 icall_name = "specific_trampoline_generic_class_init";
3703 sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3704 sig->ret = &mono_get_void_class ()->byval_arg;
3705 sig->params [0] = &mono_get_intptr_class ()->byval_arg;
3706 if (cfg->compile_aot) {
3707 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3709 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, sig));
3710 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3712 mono_memory_barrier ();
3713 ctx->lmodule->generic_class_init_tramp = callee;
3716 init_bb = gen_bb (ctx, "INIT_BB");
3717 noinit_bb = gen_bb (ctx, "NOINIT_BB");
3719 LLVMBuildCondBr (ctx->builder, cmp, noinit_bb, init_bb);
3721 builder = create_builder (ctx);
3722 ctx->builder = builder;
3723 LLVMPositionBuilderAtEnd (builder, init_bb);
3724 args [0] = convert (ctx, lhs, IntPtrType ());
3725 emit_call (ctx, bb, &builder, callee, args, 1);
3726 LLVMBuildBr (builder, noinit_bb);
3728 builder = create_builder (ctx);
3729 ctx->builder = builder;
3730 LLVMPositionBuilderAtEnd (builder, noinit_bb);
3732 ctx->bblocks [bb->block_num].end_bblock = noinit_bb;
3737 LLVMValueRef indexes [2];
3739 LLVMValueRef got_entry_addr;
3742 * FIXME: Can't allocate from the cfg mempool since that is freed if
3743 * the LLVM compile fails.
3745 ji = g_new0 (MonoJumpInfo, 1);
3746 ji->type = (MonoJumpInfoType)ins->inst_i1;
3747 ji->data.target = ins->inst_p0;
3749 ji = mono_aot_patch_info_dup (ji);
3751 ji->next = cfg->patch_info;
3752 cfg->patch_info = ji;
3754 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3755 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3756 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3758 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3759 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3760 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3762 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3763 set_invariant_load_flag (values [ins->dreg]);
3766 case OP_NOT_REACHED:
3767 LLVMBuildUnreachable (builder);
3768 has_terminator = TRUE;
3769 g_assert (bb->block_num < cfg->max_block_num);
3770 ctx->unreachable [bb->block_num] = TRUE;
3771 /* Might have instructions after this */
3773 MonoInst *next = ins->next;
3775 * FIXME: If later code uses the regs defined by these instructions,
3776 * compilation will fail.
3778 MONO_DELETE_INS (bb, next);
3782 MonoInst *var = ins->inst_p0;
3784 values [ins->dreg] = addresses [var->dreg];
3788 LLVMValueRef args [1];
3790 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3791 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3795 LLVMValueRef args [1];
3797 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3798 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3802 LLVMValueRef args [1];
3805 /* This no longer seems to happen */
3807 * LLVM optimizes sqrt(nan) into undefined in
3808 * lib/Analysis/ConstantFolding.cpp
3809 * Also, sqrt(NegativeInfinity) is optimized into 0.
3811 LLVM_FAILURE (ctx, "sqrt");
3813 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3814 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3818 LLVMValueRef args [1];
3820 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3821 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3835 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3836 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3838 switch (ins->opcode) {
3841 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3845 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3849 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3853 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3856 g_assert_not_reached ();
3859 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3862 case OP_ATOMIC_EXCHANGE_I4:
3863 case OP_ATOMIC_EXCHANGE_I8: {
3864 LLVMValueRef args [2];
3867 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3868 t = LLVMInt32Type ();
3870 t = LLVMInt64Type ();
3872 g_assert (ins->inst_offset == 0);
3874 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3875 args [1] = convert (ctx, rhs, t);
3877 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3880 case OP_ATOMIC_ADD_I4:
3881 case OP_ATOMIC_ADD_I8: {
3882 LLVMValueRef args [2];
3885 if (ins->opcode == OP_ATOMIC_ADD_I4)
3886 t = LLVMInt32Type ();
3888 t = LLVMInt64Type ();
3890 g_assert (ins->inst_offset == 0);
3892 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3893 args [1] = convert (ctx, rhs, t);
3894 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3897 case OP_ATOMIC_CAS_I4:
3898 case OP_ATOMIC_CAS_I8: {
3899 LLVMValueRef args [3], val;
3902 if (ins->opcode == OP_ATOMIC_CAS_I4)
3903 t = LLVMInt32Type ();
3905 t = LLVMInt64Type ();
3907 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3909 args [1] = convert (ctx, values [ins->sreg3], t);
3911 args [2] = convert (ctx, values [ins->sreg2], t);
3912 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3913 /* cmpxchg returns a pair */
3914 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3917 case OP_MEMORY_BARRIER: {
3918 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3921 case OP_ATOMIC_LOAD_I1:
3922 case OP_ATOMIC_LOAD_I2:
3923 case OP_ATOMIC_LOAD_I4:
3924 case OP_ATOMIC_LOAD_I8:
3925 case OP_ATOMIC_LOAD_U1:
3926 case OP_ATOMIC_LOAD_U2:
3927 case OP_ATOMIC_LOAD_U4:
3928 case OP_ATOMIC_LOAD_U8:
3929 case OP_ATOMIC_LOAD_R4:
3930 case OP_ATOMIC_LOAD_R8: {
3931 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3934 gboolean sext, zext;
3936 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3937 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3938 LLVMValueRef index, addr;
3940 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3945 if (ins->inst_offset != 0) {
3946 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3947 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3952 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3954 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3957 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3959 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3962 case OP_ATOMIC_STORE_I1:
3963 case OP_ATOMIC_STORE_I2:
3964 case OP_ATOMIC_STORE_I4:
3965 case OP_ATOMIC_STORE_I8:
3966 case OP_ATOMIC_STORE_U1:
3967 case OP_ATOMIC_STORE_U2:
3968 case OP_ATOMIC_STORE_U4:
3969 case OP_ATOMIC_STORE_U8:
3970 case OP_ATOMIC_STORE_R4:
3971 case OP_ATOMIC_STORE_R8: {
3972 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3975 gboolean sext, zext;
3977 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3978 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3979 LLVMValueRef index, addr, value;
3981 if (!values [ins->inst_destbasereg])
3982 LLVM_FAILURE (ctx, "inst_destbasereg");
3984 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3986 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3987 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3988 value = convert (ctx, values [ins->sreg1], t);
3990 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3993 case OP_RELAXED_NOP: {
3994 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3995 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
4002 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
4004 // 257 == FS segment register
4005 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
4007 // 256 == GS segment register
4008 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4011 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
4012 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
4013 /* See mono_amd64_emit_tls_get () */
4014 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
4016 // 256 == GS segment register
4017 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4018 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
4020 LLVM_FAILURE (ctx, "opcode tls-get");
4025 case OP_TLS_GET_REG: {
4026 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4027 /* See emit_tls_get_reg () */
4028 // 256 == GS segment register
4029 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4030 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
4032 LLVM_FAILURE (ctx, "opcode tls-get");
4041 case OP_IADD_OVF_UN:
4043 case OP_ISUB_OVF_UN:
4045 case OP_IMUL_OVF_UN:
4046 #if SIZEOF_VOID_P == 8
4048 case OP_LADD_OVF_UN:
4050 case OP_LSUB_OVF_UN:
4052 case OP_LMUL_OVF_UN:
4055 LLVMValueRef args [2], val, ovf, func;
4057 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4058 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4059 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4061 val = LLVMBuildCall (builder, func, args, 2, "");
4062 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4063 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4064 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4065 CHECK_FAILURE (ctx);
4066 builder = ctx->builder;
4072 * We currently model them using arrays. Promotion to local vregs is
4073 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4074 * so we always have an entry in cfg->varinfo for them.
4075 * FIXME: Is this needed ?
4078 MonoClass *klass = ins->klass;
4079 LLVMValueRef args [5];
4083 LLVM_FAILURE (ctx, "!klass");
4087 if (!addresses [ins->dreg])
4088 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4089 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4090 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4091 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4093 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4094 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4095 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4098 case OP_DUMMY_VZERO:
4101 case OP_STOREV_MEMBASE:
4102 case OP_LOADV_MEMBASE:
4104 MonoClass *klass = ins->klass;
4105 LLVMValueRef src = NULL, dst, args [5];
4106 gboolean done = FALSE;
4110 LLVM_FAILURE (ctx, "!klass");
4114 if (mini_is_gsharedvt_klass (cfg, klass)) {
4116 LLVM_FAILURE (ctx, "gsharedvt");
4120 switch (ins->opcode) {
4121 case OP_STOREV_MEMBASE:
4122 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4123 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4124 /* Decomposed earlier */
4125 g_assert_not_reached ();
4128 if (!addresses [ins->sreg1]) {
4130 g_assert (values [ins->sreg1]);
4131 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));
4132 LLVMBuildStore (builder, values [ins->sreg1], dst);
4135 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4136 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4139 case OP_LOADV_MEMBASE:
4140 if (!addresses [ins->dreg])
4141 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4142 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4143 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4146 if (!addresses [ins->sreg1])
4147 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4148 if (!addresses [ins->dreg])
4149 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4150 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4151 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4154 g_assert_not_reached ();
4156 CHECK_FAILURE (ctx);
4163 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4164 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4166 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4167 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4168 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4171 case OP_LLVM_OUTARG_VT:
4172 if (!addresses [ins->sreg1]) {
4173 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4174 g_assert (values [ins->sreg1]);
4175 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4177 addresses [ins->dreg] = addresses [ins->sreg1];
4183 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4185 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4188 case OP_LOADX_MEMBASE: {
4189 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4192 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4193 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4196 case OP_STOREX_MEMBASE: {
4197 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4200 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4201 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4208 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4212 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4218 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4222 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4226 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4230 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4233 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4236 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4239 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4243 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4254 LLVMValueRef v = NULL;
4256 switch (ins->opcode) {
4261 t = LLVMVectorType (LLVMInt32Type (), 4);
4262 rt = LLVMVectorType (LLVMFloatType (), 4);
4268 t = LLVMVectorType (LLVMInt64Type (), 2);
4269 rt = LLVMVectorType (LLVMDoubleType (), 2);
4272 t = LLVMInt32Type ();
4273 rt = LLVMInt32Type ();
4274 g_assert_not_reached ();
4277 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4278 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4279 switch (ins->opcode) {
4282 v = LLVMBuildAnd (builder, lhs, rhs, "");
4286 v = LLVMBuildOr (builder, lhs, rhs, "");
4290 v = LLVMBuildXor (builder, lhs, rhs, "");
4294 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4297 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4321 case OP_PADDB_SAT_UN:
4322 case OP_PADDW_SAT_UN:
4323 case OP_PSUBB_SAT_UN:
4324 case OP_PSUBW_SAT_UN:
4332 case OP_PMULW_HIGH_UN: {
4333 LLVMValueRef args [2];
4338 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4345 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4349 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4357 case OP_EXTRACTX_U2:
4359 case OP_EXTRACT_U1: {
4361 gboolean zext = FALSE;
4363 t = simd_op_to_llvm_type (ins->opcode);
4365 switch (ins->opcode) {
4373 case OP_EXTRACTX_U2:
4378 t = LLVMInt32Type ();
4379 g_assert_not_reached ();
4382 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4383 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4385 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4394 case OP_EXPAND_R8: {
4395 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4396 LLVMValueRef mask [16], v;
4399 for (i = 0; i < 16; ++i)
4400 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4402 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4404 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4405 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4410 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4413 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4416 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4419 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4422 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4425 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4436 case OP_EXTRACT_MASK:
4443 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4445 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4451 LLVMValueRef args [3];
4455 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4457 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4462 /* This is only used for implementing shifts by non-immediate */
4463 values [ins->dreg] = lhs;
4474 LLVMValueRef args [3];
4477 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4479 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4490 case OP_PSHLQ_REG: {
4491 LLVMValueRef args [3];
4494 args [1] = values [ins->sreg2];
4496 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4503 case OP_PSHUFLEW_LOW:
4504 case OP_PSHUFLEW_HIGH: {
4506 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4507 int i, mask_size = 0;
4508 int imask = ins->inst_c0;
4510 /* Convert the x86 shuffle mask to LLVM's */
4511 switch (ins->opcode) {
4514 mask [0] = ((imask >> 0) & 3);
4515 mask [1] = ((imask >> 2) & 3);
4516 mask [2] = ((imask >> 4) & 3) + 4;
4517 mask [3] = ((imask >> 6) & 3) + 4;
4518 v1 = values [ins->sreg1];
4519 v2 = values [ins->sreg2];
4523 mask [0] = ((imask >> 0) & 1);
4524 mask [1] = ((imask >> 1) & 1) + 2;
4525 v1 = values [ins->sreg1];
4526 v2 = values [ins->sreg2];
4528 case OP_PSHUFLEW_LOW:
4530 mask [0] = ((imask >> 0) & 3);
4531 mask [1] = ((imask >> 2) & 3);
4532 mask [2] = ((imask >> 4) & 3);
4533 mask [3] = ((imask >> 6) & 3);
4538 v1 = values [ins->sreg1];
4539 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4541 case OP_PSHUFLEW_HIGH:
4547 mask [4] = 4 + ((imask >> 0) & 3);
4548 mask [5] = 4 + ((imask >> 2) & 3);
4549 mask [6] = 4 + ((imask >> 4) & 3);
4550 mask [7] = 4 + ((imask >> 6) & 3);
4551 v1 = values [ins->sreg1];
4552 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4556 mask [0] = ((imask >> 0) & 3);
4557 mask [1] = ((imask >> 2) & 3);
4558 mask [2] = ((imask >> 4) & 3);
4559 mask [3] = ((imask >> 6) & 3);
4560 v1 = values [ins->sreg1];
4561 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4564 g_assert_not_reached ();
4566 for (i = 0; i < mask_size; ++i)
4567 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4569 values [ins->dreg] =
4570 LLVMBuildShuffleVector (builder, v1, v2,
4571 LLVMConstVector (mask_values, mask_size), dname);
4575 case OP_UNPACK_LOWB:
4576 case OP_UNPACK_LOWW:
4577 case OP_UNPACK_LOWD:
4578 case OP_UNPACK_LOWQ:
4579 case OP_UNPACK_LOWPS:
4580 case OP_UNPACK_LOWPD:
4581 case OP_UNPACK_HIGHB:
4582 case OP_UNPACK_HIGHW:
4583 case OP_UNPACK_HIGHD:
4584 case OP_UNPACK_HIGHQ:
4585 case OP_UNPACK_HIGHPS:
4586 case OP_UNPACK_HIGHPD: {
4588 LLVMValueRef mask_values [16];
4589 int i, mask_size = 0;
4590 gboolean low = FALSE;
4592 switch (ins->opcode) {
4593 case OP_UNPACK_LOWB:
4597 case OP_UNPACK_LOWW:
4601 case OP_UNPACK_LOWD:
4602 case OP_UNPACK_LOWPS:
4606 case OP_UNPACK_LOWQ:
4607 case OP_UNPACK_LOWPD:
4611 case OP_UNPACK_HIGHB:
4614 case OP_UNPACK_HIGHW:
4617 case OP_UNPACK_HIGHD:
4618 case OP_UNPACK_HIGHPS:
4621 case OP_UNPACK_HIGHQ:
4622 case OP_UNPACK_HIGHPD:
4626 g_assert_not_reached ();
4630 for (i = 0; i < (mask_size / 2); ++i) {
4632 mask [(i * 2) + 1] = mask_size + i;
4635 for (i = 0; i < (mask_size / 2); ++i) {
4636 mask [(i * 2)] = (mask_size / 2) + i;
4637 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4641 for (i = 0; i < mask_size; ++i)
4642 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4644 values [ins->dreg] =
4645 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4646 LLVMConstVector (mask_values, mask_size), dname);
4651 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4652 LLVMValueRef v, val;
4654 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4655 val = LLVMConstNull (t);
4656 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4657 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4659 values [ins->dreg] = val;
4663 case OP_DUPPS_HIGH: {
4664 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4665 LLVMValueRef v1, v2, val;
4668 if (ins->opcode == OP_DUPPS_LOW) {
4669 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4670 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4672 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4673 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4675 val = LLVMConstNull (t);
4676 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4677 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4678 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4679 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4681 values [ins->dreg] = val;
4691 * EXCEPTION HANDLING
4693 case OP_IMPLICIT_EXCEPTION:
4694 /* This marks a place where an implicit exception can happen */
4695 if (bb->region != -1)
4696 LLVM_FAILURE (ctx, "implicit-exception");
4700 MonoMethodSignature *throw_sig;
4701 LLVMValueRef callee, arg;
4702 gboolean rethrow = (ins->opcode == OP_RETHROW);
4703 const char *icall_name;
4705 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4706 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4709 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4710 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4711 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4712 if (cfg->compile_aot) {
4713 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4715 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4719 * LLVM doesn't push the exception argument, so we need a different
4722 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4724 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4728 mono_memory_barrier ();
4730 ctx->lmodule->rethrow = callee;
4732 ctx->lmodule->throw = callee;
4734 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4735 emit_call (ctx, bb, &builder, callee, &arg, 1);
4738 case OP_CALL_HANDLER: {
4740 * We don't 'call' handlers, but instead simply branch to them.
4741 * The code generated by ENDFINALLY will branch back to us.
4743 LLVMBasicBlockRef noex_bb;
4745 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4747 bb_list = info->call_handler_return_bbs;
4750 * Set the indicator variable for the finally clause.
4752 lhs = info->finally_ind;
4754 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4756 /* Branch to the finally clause */
4757 LLVMBuildBr (builder, info->call_handler_target_bb);
4759 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4760 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4762 builder = ctx->builder = create_builder (ctx);
4763 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4765 bblocks [bb->block_num].end_bblock = noex_bb;
4768 case OP_START_HANDLER: {
4771 case OP_ENDFINALLY: {
4772 LLVMBasicBlockRef resume_bb;
4773 MonoBasicBlock *handler_bb;
4774 LLVMValueRef val, switch_ins, callee;
4778 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4779 g_assert (handler_bb);
4780 info = &bblocks [handler_bb->block_num];
4781 lhs = info->finally_ind;
4784 bb_list = info->call_handler_return_bbs;
4786 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4788 /* Load the finally variable */
4789 val = LLVMBuildLoad (builder, lhs, "");
4791 /* Reset the variable */
4792 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4794 /* Branch to either resume_bb, or to the bblocks in bb_list */
4795 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4797 * The other targets are added at the end to handle OP_CALL_HANDLER
4798 * opcodes processed later.
4800 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4802 builder = ctx->builder = create_builder (ctx);
4803 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4805 if (ctx->cfg->compile_aot) {
4806 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4808 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4810 LLVMBuildCall (builder, callee, NULL, 0, "");
4812 LLVMBuildUnreachable (builder);
4813 has_terminator = TRUE;
4819 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4820 LLVM_FAILURE (ctx, reason);
4825 /* Convert the value to the type required by phi nodes */
4826 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4827 if (!values [ins->dreg])
4829 values [ins->dreg] = addresses [ins->dreg];
4831 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4834 /* Add stores for volatile variables */
4835 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4836 emit_volatile_store (ctx, ins->dreg);
4839 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4840 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4842 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4843 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4844 LLVMBuildRetVoid (builder);
4847 if (bb == cfg->bb_entry)
4848 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4857 * mono_llvm_check_method_supported:
4859 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4860 * compiling a method twice.
4863 mono_llvm_check_method_supported (MonoCompile *cfg)
4867 if (cfg->method->save_lmf) {
4868 cfg->exception_message = g_strdup ("lmf");
4869 cfg->disable_llvm = TRUE;
4871 if (cfg->disable_llvm)
4875 * Nested clauses where one of the clauses is a finally clause is
4876 * not supported, because LLVM can't figure out the control flow,
4877 * probably because we resume exception handling by calling our
4878 * own function instead of using the 'resume' llvm instruction.
4880 for (i = 0; i < cfg->header->num_clauses; ++i) {
4881 for (j = 0; j < cfg->header->num_clauses; ++j) {
4882 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4883 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4885 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4886 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4887 cfg->exception_message = g_strdup ("nested clauses");
4888 cfg->disable_llvm = TRUE;
4893 if (cfg->disable_llvm)
4897 if (cfg->method->dynamic) {
4898 cfg->exception_message = g_strdup ("dynamic.");
4899 cfg->disable_llvm = TRUE;
4901 if (cfg->disable_llvm)
4906 * mono_llvm_emit_method:
4908 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4911 mono_llvm_emit_method (MonoCompile *cfg)
4914 MonoMethodSignature *sig;
4916 LLVMTypeRef method_type;
4917 LLVMValueRef method = NULL;
4919 LLVMValueRef *values;
4920 int i, max_block_num, bb_index;
4921 gboolean last = FALSE;
4922 GPtrArray *phi_values;
4923 LLVMCallInfo *linfo;
4925 LLVMModuleRef module;
4927 GPtrArray *bblock_list;
4928 MonoMethodHeader *header;
4929 MonoExceptionClause *clause;
4933 /* The code below might acquire the loader lock, so use it for global locking */
4934 mono_loader_lock ();
4936 /* Used to communicate with the callbacks */
4937 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4939 ctx = g_new0 (EmitContext, 1);
4941 ctx->mempool = cfg->mempool;
4944 * This maps vregs to the LLVM instruction defining them
4946 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4948 * This maps vregs for volatile variables to the LLVM instruction defining their
4951 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4952 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4953 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4954 phi_values = g_ptr_array_sized_new (256);
4956 * This signals whenever the vreg was defined by a phi node with no input vars
4957 * (i.e. all its input bblocks end with NOT_REACHABLE).
4959 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4960 /* Whenever the bblock is unreachable */
4961 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4963 bblock_list = g_ptr_array_sized_new (256);
4965 ctx->values = values;
4966 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4967 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4969 if (cfg->compile_aot) {
4970 ctx->lmodule = &aot_module;
4971 method_name = mono_aot_get_method_name (cfg);
4972 cfg->llvm_method_name = g_strdup (method_name);
4974 init_jit_module (cfg->domain);
4975 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4976 method_name = mono_method_full_name (cfg->method, TRUE);
4979 module = ctx->module = ctx->lmodule->module;
4982 LLVM_FAILURE (ctx, "gsharedvt");
4986 static int count = 0;
4989 if (g_getenv ("LLVM_COUNT")) {
4990 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4991 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4995 if (count > atoi (g_getenv ("LLVM_COUNT")))
4996 LLVM_FAILURE (ctx, "");
5001 sig = mono_method_signature (cfg->method);
5004 linfo = mono_arch_get_llvm_call_info (cfg, sig);
5006 CHECK_FAILURE (ctx);
5009 linfo->rgctx_arg = TRUE;
5010 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
5011 CHECK_FAILURE (ctx);
5014 * This maps parameter indexes in the original signature to the indexes in
5015 * the LLVM signature.
5017 ctx->pindexes = sinfo.pindexes;
5019 method = LLVMAddFunction (module, method_name, method_type);
5020 ctx->lmethod = method;
5022 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
5023 LLVMSetLinkage (method, LLVMPrivateLinkage);
5025 LLVMAddFunctionAttr (method, LLVMUWTable);
5027 if (cfg->compile_aot) {
5028 LLVMSetLinkage (method, LLVMInternalLinkage);
5029 if (ctx->lmodule->external_symbols) {
5030 LLVMSetLinkage (method, LLVMExternalLinkage);
5031 LLVMSetVisibility (method, LLVMHiddenVisibility);
5034 LLVMSetLinkage (method, LLVMPrivateLinkage);
5037 if (cfg->method->save_lmf)
5038 LLVM_FAILURE (ctx, "lmf");
5040 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
5041 LLVM_FAILURE (ctx, "pinvoke signature");
5043 header = cfg->header;
5044 for (i = 0; i < header->num_clauses; ++i) {
5045 clause = &header->clauses [i];
5046 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5047 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5049 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5050 /* We can't handle inlined methods with clauses */
5051 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5053 if (linfo->rgctx_arg) {
5054 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5056 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5057 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5058 * CC_X86_64_Mono in X86CallingConv.td.
5060 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5061 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5063 if (cfg->vret_addr) {
5064 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5065 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5068 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5069 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5072 names = g_new (char *, sig->param_count);
5073 mono_method_get_param_names (cfg->method, (const char **) names);
5075 for (i = 0; i < sig->param_count; ++i) {
5078 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5079 if (names [i] && names [i][0] != '\0')
5080 name = g_strdup_printf ("arg_%s", names [i]);
5082 name = g_strdup_printf ("arg_%d", i);
5083 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5085 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5086 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5090 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5091 ctx->minfo = mono_debug_lookup_method (cfg->method);
5092 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5096 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5097 max_block_num = MAX (max_block_num, bb->block_num);
5098 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5100 /* Add branches between non-consecutive bblocks */
5101 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5102 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5103 bb->next_bb != bb->last_ins->inst_false_bb) {
5105 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5106 inst->opcode = OP_BR;
5107 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5108 mono_bblock_add_inst (bb, inst);
5113 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5114 * was later optimized away, so clear these flags, and add them back for the still
5115 * present OP_LDADDR instructions.
5117 for (i = 0; i < cfg->next_vreg; ++i) {
5120 ins = get_vreg_to_inst (cfg, i);
5121 if (ins && ins != cfg->rgctx_var)
5122 ins->flags &= ~MONO_INST_INDIRECT;
5126 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5128 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5130 LLVMBuilderRef builder;
5132 char dname_buf[128];
5134 builder = create_builder (ctx);
5136 for (ins = bb->code; ins; ins = ins->next) {
5137 switch (ins->opcode) {
5142 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5144 CHECK_FAILURE (ctx);
5146 if (ins->opcode == OP_VPHI) {
5147 /* Treat valuetype PHI nodes as operating on the address itself */
5148 g_assert (ins->klass);
5149 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5153 * Have to precreate these, as they can be referenced by
5154 * earlier instructions.
5156 sprintf (dname_buf, "t%d", ins->dreg);
5158 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5160 if (ins->opcode == OP_VPHI)
5161 ctx->addresses [ins->dreg] = values [ins->dreg];
5163 g_ptr_array_add (phi_values, values [ins->dreg]);
5166 * Set the expected type of the incoming arguments since these have
5167 * to have the same type.
5169 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5170 int sreg1 = ins->inst_phi_args [i + 1];
5173 ctx->vreg_types [sreg1] = phi_type;
5178 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5187 * Create an ordering for bblocks, use the depth first order first, then
5188 * put the exception handling bblocks last.
5190 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5191 bb = cfg->bblocks [bb_index];
5192 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5193 g_ptr_array_add (bblock_list, bb);
5194 bblocks [bb->block_num].added = TRUE;
5198 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5199 if (!bblocks [bb->block_num].added)
5200 g_ptr_array_add (bblock_list, bb);
5204 * Second pass: generate code.
5206 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5207 bb = g_ptr_array_index (bblock_list, bb_index);
5209 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5212 process_bb (ctx, bb);
5213 CHECK_FAILURE (ctx);
5216 /* Add incoming phi values */
5217 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5218 GSList *l, *ins_list;
5220 ins_list = bblocks [bb->block_num].phi_nodes;
5222 for (l = ins_list; l; l = l->next) {
5223 PhiNode *node = l->data;
5224 MonoInst *phi = node->phi;
5225 int sreg1 = node->sreg;
5226 LLVMBasicBlockRef in_bb;
5231 in_bb = get_end_bb (ctx, node->in_bb);
5233 if (ctx->unreachable [node->in_bb->block_num])
5236 if (!values [sreg1])
5237 /* Can happen with values in EH clauses */
5238 LLVM_FAILURE (ctx, "incoming phi sreg1");
5240 if (phi->opcode == OP_VPHI) {
5241 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5242 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5244 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5246 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5247 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5248 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5253 /* Create the SWITCH statements for ENDFINALLY instructions */
5254 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5255 BBInfo *info = &bblocks [bb->block_num];
5257 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5258 LLVMValueRef switch_ins = l->data;
5259 GSList *bb_list = info->call_handler_return_bbs;
5261 for (i = 0; i < g_slist_length (bb_list); ++i)
5262 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5266 if (cfg->verbose_level > 1)
5267 mono_llvm_dump_value (method);
5269 if (cfg->compile_aot)
5270 mark_as_used (ctx->lmodule, method);
5272 if (cfg->compile_aot) {
5273 LLVMValueRef md_args [16];
5274 LLVMValueRef md_node;
5277 method_index = mono_aot_get_method_index (cfg->orig_method);
5278 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5279 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5280 md_node = LLVMMDNode (md_args, 2);
5281 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5282 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5285 if (cfg->compile_aot) {
5286 /* Don't generate native code, keep the LLVM IR */
5287 if (cfg->compile_aot && cfg->verbose_level)
5288 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5290 //LLVMVerifyFunction(method, 0);
5292 //LLVMVerifyFunction(method, 0);
5293 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5295 if (cfg->verbose_level > 1)
5296 mono_llvm_dump_value (method);
5298 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5300 /* Set by emit_cb */
5301 g_assert (cfg->code_len);
5303 /* FIXME: Free the LLVM IL for the function */
5306 if (ctx->lmodule->method_to_lmethod)
5307 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5314 /* Need to add unused phi nodes as they can be referenced by other values */
5315 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5316 LLVMBuilderRef builder;
5318 builder = create_builder (ctx);
5319 LLVMPositionBuilderAtEnd (builder, phi_bb);
5321 for (i = 0; i < phi_values->len; ++i) {
5322 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5323 if (LLVMGetInstructionParent (v) == NULL)
5324 LLVMInsertIntoBuilder (builder, v);
5327 LLVMDeleteFunction (method);
5332 g_free (ctx->addresses);
5333 g_free (ctx->vreg_types);
5334 g_free (ctx->vreg_cli_types);
5335 g_free (ctx->pindexes);
5336 g_free (ctx->is_dead);
5337 g_free (ctx->unreachable);
5338 g_ptr_array_free (phi_values, TRUE);
5339 g_free (ctx->bblocks);
5340 g_hash_table_destroy (ctx->region_to_handler);
5341 g_hash_table_destroy (ctx->clause_to_handler);
5342 g_free (method_name);
5343 g_ptr_array_free (bblock_list, TRUE);
5345 for (l = ctx->builders; l; l = l->next) {
5346 LLVMBuilderRef builder = l->data;
5347 LLVMDisposeBuilder (builder);
5352 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5354 mono_loader_unlock ();
5358 * mono_llvm_emit_call:
5360 * Same as mono_arch_emit_call () for LLVM.
5363 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5366 MonoMethodSignature *sig;
5367 int i, n, stack_size;
5372 sig = call->signature;
5373 n = sig->param_count + sig->hasthis;
5375 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5377 if (cfg->disable_llvm)
5380 if (sig->call_convention == MONO_CALL_VARARG) {
5381 cfg->exception_message = g_strdup ("varargs");
5382 cfg->disable_llvm = TRUE;
5385 for (i = 0; i < n; ++i) {
5388 ainfo = call->cinfo->args + i;
5390 in = call->args [i];
5392 /* Simply remember the arguments */
5393 switch (ainfo->storage) {
5395 case LLVMArgInFPReg: {
5396 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5399 opcode = mono_type_to_regmove (cfg, t);
5400 if (opcode == OP_FMOVE) {
5401 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5402 ins->dreg = mono_alloc_freg (cfg);
5403 } else if (opcode == OP_LMOVE) {
5404 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5405 ins->dreg = mono_alloc_lreg (cfg);
5407 MONO_INST_NEW (cfg, ins, OP_MOVE);
5408 ins->dreg = mono_alloc_ireg (cfg);
5410 ins->sreg1 = in->dreg;
5413 case LLVMArgVtypeByVal:
5414 case LLVMArgVtypeInReg:
5415 case LLVMArgAsIArgs:
5416 case LLVMArgAsFpArgs:
5417 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5418 ins->dreg = mono_alloc_ireg (cfg);
5419 ins->sreg1 = in->dreg;
5420 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5423 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5424 cfg->exception_message = g_strdup ("ainfo->storage");
5425 cfg->disable_llvm = TRUE;
5429 if (!cfg->disable_llvm) {
5430 MONO_ADD_INS (cfg->cbb, ins);
5431 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5436 static unsigned char*
5437 alloc_cb (LLVMValueRef function, int size)
5441 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5445 return mono_domain_code_reserve (cfg->domain, size);
5447 return mono_domain_code_reserve (mono_domain_get (), size);
5452 emitted_cb (LLVMValueRef function, void *start, void *end)
5456 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5458 cfg->code_len = (guint8*)end - (guint8*)start;
5462 exception_cb (void *data)
5465 MonoJitExceptionInfo *ei;
5466 guint32 ei_len, i, j, nested_len, nindex;
5467 gpointer *type_info;
5468 int this_reg, this_offset;
5470 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5474 * data points to a DWARF FDE structure, convert it to our unwind format and
5476 * An alternative would be to save it directly, and modify our unwinder to work
5479 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);
5480 if (cfg->verbose_level > 1)
5481 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5483 /* Count nested clauses */
5485 for (i = 0; i < ei_len; ++i) {
5486 for (j = 0; j < ei_len; ++j) {
5487 gint32 cindex1 = *(gint32*)type_info [i];
5488 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5489 gint32 cindex2 = *(gint32*)type_info [j];
5490 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5492 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5498 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5499 cfg->llvm_ex_info_len = ei_len + nested_len;
5500 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5501 /* Fill the rest of the information from the type info */
5502 for (i = 0; i < ei_len; ++i) {
5503 gint32 clause_index = *(gint32*)type_info [i];
5504 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5506 cfg->llvm_ex_info [i].flags = clause->flags;
5507 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5508 cfg->llvm_ex_info [i].clause_index = clause_index;
5512 * For nested clauses, the LLVM produced exception info associates the try interval with
5513 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5514 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5515 * and everything else from the nested clause.
5518 for (i = 0; i < ei_len; ++i) {
5519 for (j = 0; j < ei_len; ++j) {
5520 gint32 cindex1 = *(gint32*)type_info [i];
5521 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5522 gint32 cindex2 = *(gint32*)type_info [j];
5523 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5525 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5526 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5527 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5528 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5529 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5530 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5535 g_assert (nindex == ei_len + nested_len);
5536 cfg->llvm_this_reg = this_reg;
5537 cfg->llvm_this_offset = this_offset;
5539 /* type_info [i] is cfg mempool allocated, no need to free it */
5546 dlsym_cb (const char *name, void **symbol)
5552 if (!strcmp (name, "__bzero")) {
5553 *symbol = (void*)bzero;
5555 current = mono_dl_open (NULL, 0, NULL);
5558 err = mono_dl_symbol (current, name, symbol);
5560 mono_dl_close (current);
5562 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5563 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5569 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5571 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5575 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5577 LLVMTypeRef param_types [4];
5579 param_types [0] = param_type1;
5580 param_types [1] = param_type2;
5582 AddFunc (module, name, ret_type, param_types, 2);
5586 add_intrinsics (LLVMModuleRef module)
5588 /* Emit declarations of instrinsics */
5590 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5591 * type doesn't seem to do any locking.
5594 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5596 memset_param_count = 5;
5597 memset_func_name = "llvm.memset.p0i8.i32";
5599 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5603 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5605 memcpy_param_count = 5;
5606 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5608 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5612 LLVMTypeRef params [] = { LLVMDoubleType () };
5614 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5615 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5616 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5618 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5619 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5623 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5624 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5625 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5627 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5628 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5629 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5630 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5631 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5632 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5633 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5637 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5638 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5639 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5641 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5642 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5643 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5644 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5645 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5646 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5651 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5653 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5656 /* SSE intrinsics */
5657 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5659 LLVMTypeRef ret_type, arg_types [16];
5662 ret_type = type_to_simd_type (MONO_TYPE_I4);
5663 arg_types [0] = ret_type;
5664 arg_types [1] = ret_type;
5665 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5666 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5668 ret_type = type_to_simd_type (MONO_TYPE_I2);
5669 arg_types [0] = ret_type;
5670 arg_types [1] = ret_type;
5671 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5672 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5673 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5674 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5675 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5676 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5677 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5678 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5679 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5680 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5682 ret_type = type_to_simd_type (MONO_TYPE_I1);
5683 arg_types [0] = ret_type;
5684 arg_types [1] = ret_type;
5685 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5686 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5687 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5688 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5689 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5690 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5691 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5693 ret_type = type_to_simd_type (MONO_TYPE_R8);
5694 arg_types [0] = ret_type;
5695 arg_types [1] = ret_type;
5696 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5697 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5698 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5699 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5700 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5702 ret_type = type_to_simd_type (MONO_TYPE_R4);
5703 arg_types [0] = ret_type;
5704 arg_types [1] = ret_type;
5705 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5706 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5707 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5708 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5709 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5712 ret_type = type_to_simd_type (MONO_TYPE_I1);
5713 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5714 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5715 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5716 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5717 ret_type = type_to_simd_type (MONO_TYPE_I2);
5718 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5719 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5720 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5721 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5724 ret_type = type_to_simd_type (MONO_TYPE_R8);
5725 arg_types [0] = ret_type;
5726 arg_types [1] = ret_type;
5727 arg_types [2] = LLVMInt8Type ();
5728 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5729 ret_type = type_to_simd_type (MONO_TYPE_R4);
5730 arg_types [0] = ret_type;
5731 arg_types [1] = ret_type;
5732 arg_types [2] = LLVMInt8Type ();
5733 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5735 /* Conversion ops */
5736 ret_type = type_to_simd_type (MONO_TYPE_R8);
5737 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5738 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5739 ret_type = type_to_simd_type (MONO_TYPE_R4);
5740 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5741 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5742 ret_type = type_to_simd_type (MONO_TYPE_I4);
5743 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5744 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5745 ret_type = type_to_simd_type (MONO_TYPE_I4);
5746 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5747 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5748 ret_type = type_to_simd_type (MONO_TYPE_R4);
5749 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5750 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5751 ret_type = type_to_simd_type (MONO_TYPE_R8);
5752 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5753 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5755 ret_type = type_to_simd_type (MONO_TYPE_I4);
5756 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5757 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5758 ret_type = type_to_simd_type (MONO_TYPE_I4);
5759 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5760 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5763 ret_type = type_to_simd_type (MONO_TYPE_R8);
5764 arg_types [0] = ret_type;
5765 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5766 ret_type = type_to_simd_type (MONO_TYPE_R4);
5767 arg_types [0] = ret_type;
5768 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5769 ret_type = type_to_simd_type (MONO_TYPE_R4);
5770 arg_types [0] = ret_type;
5771 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5772 ret_type = type_to_simd_type (MONO_TYPE_R4);
5773 arg_types [0] = ret_type;
5774 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5777 ret_type = type_to_simd_type (MONO_TYPE_I2);
5778 arg_types [0] = ret_type;
5779 arg_types [1] = LLVMInt32Type ();
5780 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5781 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5782 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5783 ret_type = type_to_simd_type (MONO_TYPE_I4);
5784 arg_types [0] = ret_type;
5785 arg_types [1] = LLVMInt32Type ();
5786 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5787 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5788 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5789 ret_type = type_to_simd_type (MONO_TYPE_I8);
5790 arg_types [0] = ret_type;
5791 arg_types [1] = LLVMInt32Type ();
5792 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5793 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5796 ret_type = LLVMInt32Type ();
5797 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5798 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5801 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5804 /* Load/Store intrinsics */
5806 LLVMTypeRef arg_types [5];
5810 for (i = 1; i <= 8; i *= 2) {
5811 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5812 arg_types [1] = LLVMInt32Type ();
5813 arg_types [2] = LLVMInt1Type ();
5814 arg_types [3] = LLVMInt32Type ();
5815 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5816 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5818 arg_types [0] = LLVMIntType (i * 8);
5819 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5820 arg_types [2] = LLVMInt32Type ();
5821 arg_types [3] = LLVMInt1Type ();
5822 arg_types [4] = LLVMInt32Type ();
5823 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5824 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5830 add_types (MonoLLVMModule *lmodule)
5832 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5836 mono_llvm_init (void)
5838 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5842 init_jit_module (MonoDomain *domain)
5844 MonoJitICallInfo *info;
5845 MonoJitDomainInfo *dinfo;
5846 MonoLLVMModule *module;
5849 dinfo = domain_jit_info (domain);
5850 if (dinfo->llvm_module)
5853 mono_loader_lock ();
5855 if (dinfo->llvm_module) {
5856 mono_loader_unlock ();
5860 module = g_new0 (MonoLLVMModule, 1);
5862 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5863 module->module = LLVMModuleCreateWithName (name);
5865 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5867 add_intrinsics (module->module);
5870 module->llvm_types = g_hash_table_new (NULL, NULL);
5872 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5874 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5876 mono_memory_barrier ();
5878 dinfo->llvm_module = module;
5880 mono_loader_unlock ();
5884 mono_llvm_cleanup (void)
5886 if (aot_module.module)
5887 LLVMDisposeModule (aot_module.module);
5889 LLVMContextDispose (LLVMGetGlobalContext ());
5893 mono_llvm_free_domain_info (MonoDomain *domain)
5895 MonoJitDomainInfo *info = domain_jit_info (domain);
5896 MonoLLVMModule *module = info->llvm_module;
5902 if (module->llvm_types)
5903 g_hash_table_destroy (module->llvm_types);
5905 mono_llvm_dispose_ee (module->mono_ee);
5907 if (module->bb_names) {
5908 for (i = 0; i < module->bb_names_len; ++i)
5909 g_free (module->bb_names [i]);
5910 g_free (module->bb_names);
5912 //LLVMDisposeModule (module->module);
5916 info->llvm_module = NULL;
5920 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5922 /* Delete previous module */
5923 if (aot_module.plt_entries)
5924 g_hash_table_destroy (aot_module.plt_entries);
5925 if (aot_module.module)
5926 LLVMDisposeModule (aot_module.module);
5928 memset (&aot_module, 0, sizeof (aot_module));
5930 aot_module.module = LLVMModuleCreateWithName ("aot");
5931 aot_module.got_symbol = got_symbol;
5932 aot_module.external_symbols = external_symbols;
5933 aot_module.emit_dwarf = emit_dwarf;
5934 /* The first few entries are reserved */
5935 aot_module.max_got_offset = 16;
5937 add_intrinsics (aot_module.module);
5938 add_types (&aot_module);
5942 * We couldn't compute the type of the LLVM global representing the got because
5943 * its size is only known after all the methods have been emitted. So create
5944 * a dummy variable, and replace all uses it with the real got variable when
5945 * its size is known in mono_llvm_emit_aot_module ().
5948 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5950 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5951 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5954 /* Add a dummy personality function */
5956 LLVMBasicBlockRef lbb;
5957 LLVMBuilderRef lbuilder;
5958 LLVMValueRef personality;
5960 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5961 LLVMSetLinkage (personality, LLVMInternalLinkage);
5962 lbb = LLVMAppendBasicBlock (personality, "BB0");
5963 lbuilder = LLVMCreateBuilder ();
5964 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5965 LLVMBuildRetVoid (lbuilder);
5966 mark_as_used (&aot_module, personality);
5969 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5970 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5971 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5972 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5976 * Emit the aot module into the LLVM bitcode file FILENAME.
5979 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5981 LLVMTypeRef got_type;
5982 LLVMValueRef real_got;
5983 MonoLLVMModule *module = &aot_module;
5986 * Create the real got variable and replace all uses of the dummy variable with
5989 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5990 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5991 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5992 if (module->external_symbols) {
5993 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5994 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5996 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5998 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
6000 mark_as_used (&aot_module, real_got);
6002 /* Delete the dummy got so it doesn't become a global */
6003 LLVMDeleteGlobal (aot_module.got_var);
6005 emit_llvm_used (&aot_module);
6006 emit_dbg_info (&aot_module, filename, cu_name);
6008 /* Replace PLT entries for directly callable methods with the methods themselves */
6010 GHashTableIter iter;
6012 LLVMValueRef callee;
6014 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6015 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6016 if (mono_aot_is_direct_callable (ji)) {
6017 LLVMValueRef lmethod;
6019 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6020 /* The types might not match because the caller might pass an rgctx */
6021 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6022 mono_llvm_replace_uses_of (callee, lmethod);
6023 mono_aot_mark_unused_llvm_plt_entry (ji);
6033 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6034 g_assert_not_reached ();
6039 LLVMWriteBitcodeToFile (aot_module.module, filename);
6044 md_string (const char *s)
6046 return LLVMMDString (s, strlen (s));
6049 /* Debugging support */
6052 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6054 LLVMModuleRef module = lmodule->module;
6055 LLVMValueRef args [16], cu_args [16], cu, ver;
6057 char *build_info, *s, *dir;
6060 * This can only be enabled when LLVM code is emitted into a separate object
6061 * file, since the AOT compiler also emits dwarf info,
6062 * and the abbrev indexes will not be correct since llvm has added its own
6065 if (!lmodule->emit_dwarf)
6069 * Emit dwarf info in the form of LLVM metadata. There is some
6070 * out-of-date documentation at:
6071 * http://llvm.org/docs/SourceLevelDebugging.html
6072 * but most of this was gathered from the llvm and
6077 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6078 /* CU name/compilation dir */
6079 dir = g_path_get_dirname (filename);
6080 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6081 args [1] = LLVMMDString (dir, strlen (dir));
6082 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6085 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6087 build_info = mono_get_runtime_build_info ();
6088 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6089 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6090 g_free (build_info);
6092 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6094 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6095 /* Runtime version */
6096 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6098 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6099 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6101 if (lmodule->subprogram_mds) {
6105 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6106 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6107 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6108 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6110 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6113 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6114 /* Imported modules */
6115 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6117 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6118 /* DebugEmissionKind = FullDebug */
6119 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6120 cu = LLVMMDNode (cu_args, n_cuargs);
6121 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6123 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6124 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6125 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6126 ver = LLVMMDNode (args, 3);
6127 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6129 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6130 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6131 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6132 ver = LLVMMDNode (args, 3);
6133 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6137 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6139 MonoLLVMModule *module = ctx->lmodule;
6140 MonoDebugMethodInfo *minfo = ctx->minfo;
6141 char *source_file, *dir, *filename;
6142 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6143 MonoSymSeqPoint *sym_seq_points;
6149 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6151 source_file = g_strdup ("<unknown>");
6152 dir = g_path_get_dirname (source_file);
6153 filename = g_path_get_basename (source_file);
6155 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6156 args [0] = md_string (filename);
6157 args [1] = md_string (dir);
6158 ctx_args [1] = LLVMMDNode (args, 2);
6159 ctx_md = LLVMMDNode (ctx_args, 2);
6161 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6162 type_args [1] = NULL;
6163 type_args [2] = NULL;
6164 type_args [3] = LLVMMDString ("", 0);
6165 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6166 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6167 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6168 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6169 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6170 type_args [9] = NULL;
6171 type_args [10] = NULL;
6172 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6173 type_args [12] = NULL;
6174 type_args [13] = NULL;
6175 type_args [14] = NULL;
6176 type_md = LLVMMDNode (type_args, 14);
6178 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6179 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6180 /* Source directory + file pair */
6181 args [0] = md_string (filename);
6182 args [1] = md_string (dir);
6183 md_args [1] = LLVMMDNode (args ,2);
6184 md_args [2] = ctx_md;
6185 md_args [3] = md_string (cfg->method->name);
6186 md_args [4] = md_string (name);
6187 md_args [5] = md_string (name);
6190 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6192 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6194 md_args [7] = type_md;
6196 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6198 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6200 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6201 /* Index into a virtual function */
6202 md_args [11] = NULL;
6203 md_args [12] = NULL;
6205 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6207 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6208 /* Pointer to LLVM function */
6209 md_args [15] = method;
6210 /* Function template parameter */
6211 md_args [16] = NULL;
6212 /* Function declaration descriptor */
6213 md_args [17] = NULL;
6214 /* List of function variables */
6215 md_args [18] = LLVMMDNode (args, 0);
6217 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6218 md = LLVMMDNode (md_args, 20);
6220 if (!module->subprogram_mds)
6221 module->subprogram_mds = g_ptr_array_new ();
6222 g_ptr_array_add (module->subprogram_mds, md);
6226 g_free (source_file);
6227 g_free (sym_seq_points);
6233 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6235 MonoCompile *cfg = ctx->cfg;
6237 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6238 MonoDebugSourceLocation *loc;
6239 LLVMValueRef loc_md, md_args [16];
6242 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6246 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6247 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6248 md_args [nmd_args ++] = ctx->dbg_md;
6249 md_args [nmd_args ++] = NULL;
6250 loc_md = LLVMMDNode (md_args, nmd_args);
6251 LLVMSetCurrentDebugLocation (builder, loc_md);
6252 mono_debug_symfile_free_location (loc);
6259 - Emit LLVM IR from the mono IR using the LLVM C API.
6260 - The original arch specific code remains, so we can fall back to it if we run
6261 into something we can't handle.
6265 A partial list of issues:
6266 - Handling of opcodes which can throw exceptions.
6268 In the mono JIT, these are implemented using code like this:
6275 push throw_pos - method
6276 call <exception trampoline>
6278 The problematic part is push throw_pos - method, which cannot be represented
6279 in the LLVM IR, since it does not support label values.
6280 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6281 be implemented in JIT mode ?
6282 -> a possible but slower implementation would use the normal exception
6283 throwing code but it would need to control the placement of the throw code
6284 (it needs to be exactly after the compare+branch).
6285 -> perhaps add a PC offset intrinsics ?
6287 - efficient implementation of .ovf opcodes.
6289 These are currently implemented as:
6290 <ins which sets the condition codes>
6293 Some overflow opcodes are now supported by LLVM SVN.
6295 - exception handling, unwinding.
6296 - SSA is disabled for methods with exception handlers
6297 - How to obtain unwind info for LLVM compiled methods ?
6298 -> this is now solved by converting the unwind info generated by LLVM
6300 - LLVM uses the c++ exception handling framework, while we use our home grown
6301 code, and couldn't use the c++ one:
6302 - its not supported under VC++, other exotic platforms.
6303 - it might be impossible to support filter clauses with it.
6307 The trampolines need a predictable call sequence, since they need to disasm
6308 the calling code to obtain register numbers / offsets.
6310 LLVM currently generates this code in non-JIT mode:
6311 mov -0x98(%rax),%eax
6313 Here, the vtable pointer is lost.
6314 -> solution: use one vtable trampoline per class.
6316 - passing/receiving the IMT pointer/RGCTX.
6317 -> solution: pass them as normal arguments ?
6321 LLVM does not allow the specification of argument registers etc. This means
6322 that all calls are made according to the platform ABI.
6324 - passing/receiving vtypes.
6326 Vtypes passed/received in registers are handled by the front end by using
6327 a signature with scalar arguments, and loading the parts of the vtype into those
6330 Vtypes passed on the stack are handled using the 'byval' attribute.
6334 Supported though alloca, we need to emit the load/store code.
6338 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6339 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6340 This is made easier because the IR is already in SSA form.
6341 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6342 types are frequently used incorrectly.
6347 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6348 it with the file containing the methods emitted by the JIT and the AOT data
6352 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6353 * - each bblock should end with a branch
6354 * - setting the return value, making cfg->ret non-volatile
6355 * - avoid some transformations in the JIT which make it harder for us to generate
6357 * - use pointer types to help optimizations.